Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparator for sorting an object arraylist by float parameter

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

like image 761
Pedro Neves Avatar asked Sep 01 '13 21:09

Pedro Neves


4 Answers

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;
like image 140
user949300 Avatar answered Oct 19 '22 09:10

user949300


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.

like image 27
SJuan76 Avatar answered Oct 19 '22 09:10

SJuan76


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()))
like image 37
Java Devil Avatar answered Oct 19 '22 10:10

Java Devil


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)

like image 1
Francesco Capodanno Avatar answered Oct 19 '22 09:10

Francesco Capodanno