Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting in Descending order using Comparator

Tags:

java

sorting

I'm trying to sort the list in descending order using Comparator Interface. But the values are not sorted in descending order. Not sure what i'm doing wrong here.

public class Student {

    int rollNo;
    String name;
    int age;
    
    public Student(int RollNo, String Name, int Age){
        this.rollNo = RollNo;
        this.name = Name;
        this.age = Age;
    }
}

public class AgeComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        return o1.age > o2.age ? 1 :(o1.age < o2.age ? -1 : 0); //Ascending
         
        //return o1.age < o2.age ? -1 :(o1.age > o2.age ? 1 : 0); // Descending
    }

}

public class Comparator_Sort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        ArrayList<Student> al = new ArrayList<Student>();
        al.add(new Student(5978, "Vishnu", 50));
        al.add(new Student(5979, "Vasanth", 30));
        al.add(new Student(5980, "Santhosh", 40));
        al.add(new Student(5981, "Santhosh", 20));
        al.add(new Student(5982, "Santhosh", 10));
        al.add(new Student(5983, "Santhosh", 5));
        
        
        Collections.sort(al, new AgeComparator());
        
        for(Student s : al){
            System.out.println(s.rollNo+" "+s.name+" "+s.age);
        }
    }
}

I can be able to sort the list in ascending order, whereas i'm unable to do it for descending order

return o1.age > o2.age ? 1 :(o1.age < o2.age ? -1 : 0); //Sorted in Ascending
return o1.age < o2.age ? -1 :(o1.age > o2.age ? 1 : 0); // Not sorted in Descending

Comparator documentation -- Returns: a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. The source is found from here

Can anyone tell me why the sorting for descending is not working?

like image 444
Aishu Avatar asked Dec 14 '16 11:12

Aishu


3 Answers

Your two ternary conditional operators produce the same result (since you swapped both > with < and -1 with 1):

return o1.age > o2.age ? 1 :(o1.age < o2.age ? -1 : 0); //Sorted in Ascending
return o1.age < o2.age ? -1 :(o1.age > o2.age ? 1 : 0); // Not sorted in Descending

For descending order you need :

return o1.age > o2.age ? -1 :(o1.age < o2.age ? 1 : 0);
like image 128
Eran Avatar answered Sep 30 '22 15:09

Eran


@Eran already pointed out the error in your comparator.

I'd like to add that you may just return o1.age - o2.age. The result of comparison does not have to be exactly -1 or 1 for < or > it may be just negative or positive.

And you could have also called Comparator.reversed. Or Comparator.comparing(Student::getAge).reversed().

like image 39
lexicore Avatar answered Sep 30 '22 14:09

lexicore


Abusing ternary conditions is error-prone because not readable.

Why not simply write classic if-else-if for the descending comparator ?

public class AgeComparatorDesc implements Comparator<Student> {

  @Override
  public int compare(Student o1, Student o2) {
    if (o1.age > o2.age) {
        return -1;
    } else if (o1.age < o2.age) {
        return 1;
    }    
     return 0;
  }

}
like image 37
davidxxx Avatar answered Sep 30 '22 14:09

davidxxx