Sorting Using Comparator- Descending Order (User Defined Classes)

Sorting using Comparator- Descending order (User defined classes)

You can do the descending sort of a user-defined class this way overriding the compare() method,

Collections.sort(unsortedList,new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return b.getName().compareTo(a.getName());
}
});

Or by using Collection.reverse() to sort descending as user Prince mentioned in his comment.

And you can do the ascending sort like this,

Collections.sort(unsortedList,new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return a.getName().compareTo(b.getName());
}
});

Replace the above code with a Lambda expression(Java 8 onwards) we get concise:

Collections.sort(personList, (Person a, Person b) -> b.getName().compareTo(a.getName()));

As of Java 8, List has sort() method which takes Comparator as parameter(more concise) :

personList.sort((a,b)->b.getName().compareTo(a.getName()));

Here a and b are inferred as Person type by lambda expression.

Sorting in Descending order using Comparator

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);

What determines ascending or descending order in Comparator / Comparable collection class?

What is logic behind ordering object elements? how "(this.grade - s.grade)" if positive 1 moves "this.grade" front and puts "s.grade" next in order, why not other way around?

Using negative numbers to say "this is less than that", positive numbers to say "this is more than that" and 0 to say "these 2 things are equal" has been in many computer languages for 30+ years.

Who validates the compare result (+1, -1, 0) and then puts in ascending order / descending order respectively, is there any documentation that describes internal working of this part?

There are several internal classes that use the return value to reorder elements in arrays or collections including

Collections.sort()
Arrays.sort()
TreeSet

EDIT

To answer HOW that works you will have to look at the source code for each of the classes I listed above. Some of them are quite complicated to try to make the sorting as efficient as possible. But in general, it all boils down to code like this:

if( data[i].compareTo(data[j]) > 0 ){
// swap data[i] and data[j]
}

How is the rule for sorting a list in ascending order and descending order?

It's hacky. The contract for compareTo is that it returns less than 0 when the result of comparison is less, greater than 0 when greater and 0 when equal. It is not obvious what the code does. Instead, I would use Integer.compare(int, int) - something like

@Override
public int compareTo(Object o) {
return Integer.compare(this.finish, ((Activity) o).finish);
}

How to find sort order in compare method Java

You don't. There is absolutely no way to prevent a Comparator being converted to a descending-order comparator. If you are given a Comparator, then that defines ascending order, even if it's descending relative to another comparator.

If there is one unique, ascending order that you always want to use, then the type should implement Comparable, instead of having a Comparator, and you should use the natural ordering of the type.

Sort an array of custom objects in descending order on an int property

Use a Comparator and an ArrayList.

In Java 8

Use the new default and static methods on Comparator!

ArrayList<StudentInformation> infos = new ArrayList<StudentInformation>();
// fill array
Collections.sort(infos,
Comparator.comparingInt(StudentInformation::getBirthYear).reversed());

It's a brave new world! :)

Or—still better than Java 7—use lambdas!

ArrayList<StudentInformation> infos = new ArrayList<StudentInformation>();
// fill array
Collections.sort(infos, (s1, s2) ->
Integer.compare(s2.getBirthYear(), s1.getBirthYear()));

In Java 7

Use anonymous inner classes.

class StudentDateComparator implements Comparator<StudentInformation> {
public int compare(StudentInformation s1, StudentInformation s2) {
return Integer.compare(s2.getBirthYear(), s1.getBirthYear());
}
}

ArrayList<StudentInformation> infos = new ArrayList<StudentInformation>();
// fill array
Collections.sort(infos, new StudentDateComparator());

Explanation

What the Comparator does is allows anything to compare two objects of the given type (in this case, StudentInformation). You could also make StudentInformation implement Comparable<StudentInformation>, but this way is probably better because there is more than one way to compare student informations (by date, as here, but also by first name, last name, number of classes enrolled, etc.).

By swapping the order of s1 and s2 in the comparator, we induce a reverse order. Another way to do this would be to negate the compare call in the normal order, or to use a normal comparator and wrap it in Collections.reverseOrder.


You could also do this with a standard array.

StudentInformation[] infos = new StudentInformation[10];
// fill array
Arrays.sort(infos, new StudentDateComparator());


Related Topics



Leave a reply



Submit