5

How can i create a comparator to be able to sort an arraylist by a float parameter?

Imagine i have an arraylist of objects that has something like this:

ID=7 TFIDF=0.12654299 PR=25238.0
ID=4 TFIDF=0.12654299 PR=3638.0
ID=4 TFIDF=0.12654299 PR=3638.0
ID=4 TFIDF=0.12654299 PR=3638.0
ID=3 TFIDF=0.56442446 PR=14558.0
ID=1 TFIDF=0.0083091585 PR=3953.0 

I want to sort the array by TFIDF values.. As far as i know i can only sort them by integer.. Thus, im comparing zeros.

So far i have this:

Collections.sort(Contents_To_Show, new Comparator<ContentToShow>() {
            public int compare(ContentToShow o1, ContentToShow o2) {
                return (int) (o1.GetPR() - o2.GetPR());
            }
        });

But. Again, it compares me only the integer part. How can i compare the entire value?

Please help.

Thanks

2
  • As far as i know i can only sort them by integer.. Thus, im comparing zeros. Who says that? You compare them by whatever attribute you want, the only thing that matters is the compare method return value. Commented Sep 1, 2013 at 21:39
  • Well. At least it haven't the expected results. The code i posted do not sort the values i want. I used in another sorting PR values and it works, thats why i think this has something to do with float values or, at least 0.X Commented Sep 1, 2013 at 21:45

4 Answers 4

11

Followup to Pedro's followup. If you want to sort by TFIDF, then by PR,

int result = Float.compare(o1.getTFIDF(), o2.getTFIDF());
if (result == 0)
  result = Float.compare(o1.getPR(), o2.getPR());
return result;
Sign up to request clarification or add additional context in comments.

2 Comments

Ah men u just finished to save my life. Call me a noob but i developed a hell of an algorithm to organize this this way (kind of). U did it in a few line.. omg i feel terrible :D. Thanks a lot
Glad to help. I've written a lot of Comparators and eventually you figure out this idiom. Float.compare() is fairly recent, at least to my knowledge. When dealing with primitives, always look in their "wrapper" class for possible utility methods.
4

Ok, from your comment the issue that you have is that you are using the substraction code to your comparator, but as the float values difference is less than 1 (absolute value), casting to int always rounds to 0.

Use a more generic form, with if

        public int compare(ContentToShow o1, ContentToShow o2) {
            if (o1.getTFIDF() > o2.getTFIDF()) {
              return -1;
            }
            if (o1.getTFIDF() < o2.getTFIDF()) {
              return 1;
            }
            return 0
        }

As I said, how do you get the compare result value (as long as it is coherent) is not related to the sorting.

2 Comments

The code you posted works only for ints/longs because if the difference between two ints is less than 1, it is because they are both the same.
However, instead of writing you own code, use Float.compare() or Double.compare().
1

I want to sort the array by TFIDF values..

Then why are you comparing PR values with o1.GetPR()

public int compare(ContentToShow o1, ContentToShow o2) {
      return (int) (o1.GetPR() - o2.GetPR());
}

Try comparing the TFIDF values in your compare method (but as mentioned casting to int will always round to int value i.e. 0)

return (int) (o1.GetTFIDF() - o2.GetTFIDF());

So you could use

return Float.valueOf(o1.GetTFIDF()).compareTo(Float.valueOf(o2.GetTFIDF()))

Comments

1

In Java 8 with lambda functions is now very simple to compare two float in a object list. I use in this example both lambda functions and functional operations (new features in Java 8). In your main you can try this example. This example arrange people by floats that represent the height :

List<Person> people = Person.createStandardList(); // create a list with 2 standard users
Collections.sort(people, (Person p1, Person p2) -> Float.compare(p1.height_in_meter, p2.height_in_meter));

    people.stream().forEach((p) -> { // functional operation
        p.printName();
    });

This is my class Person

public class Person {

 public static List<Person> createStandardList() {
   List<Person> people = new ArrayList<>();
   Person p = new Person();
   p.name = "Administrator";
   p.surname = "admin";
   p.address = "Via standard 1";
   p.age = 26;
   p.sex = 'M';
   p.height_in_meter = 1.70f;
   p.weight_in_kg = 68.50f;
   people.add(p);
   p = new Person();
   p.name = "First";
   p.surname = "Creator";
   p.address = "Via standard 2";
   p.age = 30;
   p.sex = 'F';
   p.height_in_meter = 1.80f;
   p.weight_in_kg = 58.50f;      
   people.add(p);
   p = new Person();
   p.name = "Second";
   p.surname = "Creator";
   p.address = "Via standard 3";
   p.age = 20;
   p.sex = 'F';
   p.height_in_meter = 1.30f;
   p.weight_in_kg = 48.50f;      
   people.add(p);
   return people;

 }

 public String name;
 public String surname;
 public String address;
 public int age;
 public char sex;
 public float height_in_meter;
 public float weight_in_kg;

 public String getName() {
     return name;
 }

 public String getSurname() {
     return surname;
 }

 public float getHeight_in_meter() {
    return high_in_meter;
 }

 public float getWeight_in_kg() {
    return weight_in_kg;
 }

 public void printName() {
  System.out.println(this.name);
 }  
}

The output is :

Second

Administrator

First

So I think this example it's easier to understand JAVA 8 features. In Documentation you try a similar example but with strings that use another method. (Oracle official documentation to lambda functions with Collection example)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.