I have a list of Triple which is an user-defined class. When I sort it using Comparator
it shows weird behavior.
Consider this snippet -
List<Triple> list = new ArrayList<>();
list.add(new Triple(1,12,13)); //adding values to list
list.add(new Triple(11,3,31));
list.add(new Triple(16,6,32));
list.add(new Triple(16,8,32));
list.add(new Triple(16,7,32));
list.add(new Triple(16,9,32));
list.add(new Triple(16,5,32));
list.add(new Triple(7,21,0));
list.add(new Triple(6,22,12));
list.add(new Triple(4,22,13));
list.add(new Triple(2,77,3));
list.add(new Triple(1,8,30));
Sort Using Comparator
list.sort(
Comparator.comparingInt(Triple::getA)
.thenComparingInt(Triple::getB)
.thenComparing(Triple::getC));
list.forEach(e->System.out.printf("(%d,%d,%d) ",e.getA(),e.getB(),e.getC()));
System.out.println();
//sort A descending if for same A ascending B and for same B ascending C
list.sort(
Comparator.comparingInt(Triple::getA).reversed()
.thenComparingInt(Triple::getB)
.thenComparing(Triple::getC));
list.forEach(e->System.out.printf("(%d,%d,%d) ",e.getA(),e.getB(),e.getC()));
System.out.println();
//sort A ascending if for same A descending B and for same B ascending C
list.sort(
Comparator.comparingInt(Triple::getA)
.thenComparingInt(Triple::getB)
.reversed()
.thenComparing(Triple::getC));
list.forEach(e->System.out.printf("(%d,%d,%d) ",e.getA(),e.getB(),e.getC()));
System.out.println();
//sort A ascending if for same A ascending B and for same B descending C
list.sort(
Comparator.comparingInt(Triple::getA)
.thenComparingInt(Triple::getB)
.thenComparing(Triple::getC)
.reversed());
list.forEach(e->System.out.printf("(%d,%d,%d) ",e.getA(),e.getB(),e.getC()));
I expect the output as the list as I stated in comments -
But the output is
(16,5,32) (16,6,32) (16,7,32) (16,8,32) (16,9,32) (11,3,31) (7,21,0) (6,22,12) (4,22,13) (2,77,3) (1,8,30) (1,12,13)
(16,9,32) (16,8,32) (16,7,32) (16,6,32) (16,5,32) (11,3,31) (7,21,0) (6,22,12) (4,22,13) (2,77,3) (1,12,13) (1,8,30)
(16,9,32) (16,8,32) (16,7,32) (16,6,32) (16,5,32) (11,3,31) (7,21,0) (6,22,12) (4,22,13) (2,77,3) (1,12,13) (1,8,30)
So reversed() method reversed the earlier comparator conditions.
For your information, Triple is just class with Three variables and get set methods.
Since you define a comparator like Comparator.comparingInt(Triple::getA) .thenComparingInt(Triple::getB)
this returns a new Comparator
object that contains both previous ways of comparing the object. If you then call reversed
on this Comparator
it returns new Comparator which reverses this Comparator
- so in this case both previous conditions will be reversed.
If you want to reverse one of your comparators in the chain you can use something like :
.thenComparing(Triple::getB, Comparator.reverseOrder())
So one of your comparators can look like :
Comparator.comparingInt(Triple::getA)
.thenComparing(Triple::getB, Comparator.reverseOrder())
.thenComparing(Triple::getC)
This will only reverse B property sorting condition.