Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 - Compare multiple fields in different order using Comparator

I like to use Java 8 Comparator to sort a List of an object based on three properties. The requirement is to sort in this order - Name ascending, Age descending, City ascending. If I use reversed() on `Age it reverses previously sorted entries as well. Here is what I've tried:

Comparator.comparing((Person p) -> p.getName())
          .thenComparingInt(p -> p.getAge())
          .reversed()
          .thenComparing(p -> p.getCity());
like image 577
VinPro Avatar asked Jul 27 '18 20:07

VinPro


People also ask

Can Comparable be used to sort on multiple fields?

1. Creating Comparators for Multiple Fields. To sort on multiple fields, we must first create simple comparators for each field on which we want to sort the stream items. Then we chain these Comparator instances in the desired order to give GROUP BY effect on complete sorting behavior.

How do I compare two fields of objects in Java?

reflect. Field is used to compare two field objects. This method compares two field objects and returns true if both objects are equal otherwise false. The two Field objects are considered equal if and only if when they were declared by the same class and have the same name and type.

How do you use comparator for descending order?

In order to sort ArrayList in Descending order using Comparator, we need to use the Collections. reverseOrder() method which returns a comparator which gives the reverse of the natural ordering on a collection of objects that implement the Comparable interface.


2 Answers

Use Comparator.reverseOrder():

.thenComparing(Person::getAge, Comparator.reverseOrder())

If you want to avoid autoboxing, you can do

.thenComparing((p1, p2) -> Integer.compare(p2.getAge(), p1.getAge()))

Or

.thenComparing(Comparator.comparingInt(Person::getAge).reversed())
like image 78
shmosel Avatar answered Oct 18 '22 01:10

shmosel


There is no need to use the method Comparator::reverse. Since you want to reverse the comparison based on the integer, just negate the age -p.getAge() and it will be sorted in the descending order:

Comparator.comparing((Person p) -> p.getName())
          .thenComparingInt(p -> -p.getAge())
          .thenComparing(p -> p.getCity());
like image 41
Nikolas Charalambidis Avatar answered Oct 18 '22 03:10

Nikolas Charalambidis