142

I have an ArrayList and want sort it in descending order. I use for it java.util.stream.Stream.sorted(Comparator) method. Here is a description according Java API:

Returns a stream consisting of the elements of this stream, sorted according to the provided Comparator.

this methods return me a sort with ascending order. Which parameter should I change, just to have the descending order?

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Guforu
  • 3,835
  • 8
  • 33
  • 52

6 Answers6

263

You can use Comparator.reverseOrder() to have a comparator giving the reverse of the natural ordering.

If you want to reverse the ordering of an existing comparator, you can use Comparator.reversed().

Sample code:

Stream.of(1, 4, 2, 5)
    .sorted(Comparator.reverseOrder()); 
    // stream is now [5, 4, 2, 1]

Stream.of("foo", "test", "a")
    .sorted(Comparator.comparingInt(String::length).reversed()); 
    // stream is now [test, foo, a], sorted by descending length
Hearen
  • 7,420
  • 4
  • 53
  • 63
Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • 4
    Could you tell me why this doesn't work in my IDE? The line looks like this: `.sorted(Comparator.comparing(Map.Entry::getValue).reversed())`. For some reason the IDE starts to underline the very same parameter of `comparing()` (it didn't when I wasn't invoking `reversed()`) and says "Non-static method cannot be referenced from a static context" – Sergey Zolotarev Feb 07 '23 at 08:46
78

You can also use Comparator.comparing(Function, Comparator)
It is convenient to chain comparators when necessary, e.g.:

Comparator<SomeEntity> ENTITY_COMPARATOR = 
        Comparator.comparing(SomeEntity::getProperty1, Comparator.reverseOrder())
        .thenComparingInt(SomeEntity::getProperty2)
        .thenComparing(SomeEntity::getProperty3, Comparator.reverseOrder());
Capn Sparrow
  • 2,030
  • 2
  • 15
  • 32
dim42
  • 991
  • 7
  • 10
10

Java 8 Comparator interface has a reversed method : https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#reversed--

Dici
  • 25,226
  • 7
  • 41
  • 82
3

I found this question serching for reversing order when you have a custom comparator and the reverse is conditional (you can do it or not).

The idea proposed by Pinocchio helped me.

So here is the code:

int order = requestedOrder.equals("asc") ? 1 : -1;

Collections.sort(List<CustomObj>, new Comparator<CustomObj>() {
    public int compare(CustomObj first, CustomObj scnd) {
        return first.getComparableParam().compareTo(scnd.getComparableParam()) * order;
    }
});

Hope it helps somebody else in the future

Shinforinpola
  • 200
  • 1
  • 15
1

If you want to use class fields:

Comparator<ClassA> reversedComparator = Collections.reverseOrder(Comparator.comparing(ClassA::getSomeProperty));
cheladon
  • 121
  • 1
  • 5
0

Why not to extend the existing comperator and overwrite super and nor the result. The implementation the Comperator Interface is not nessesery but it makes it more clear what happens.

In result you get a easy reusable Class File, testable unit step and clear javadoc.

public class NorCoperator extends ExistingComperator implements Comparator<MyClass> {
    @Override
    public int compare(MyClass a, MyClass b) throws Exception {
        return super.compare(a, b)*-1;
    }
}
Pinocchio
  • 51
  • 3