Java ReverseOrder Comparator: Sort Descending
java reverseorder comparator: Learn how to reverse a comparator in Java using Comparator.reverseOrder(), Collections.reverseOrder(), and Comparator.reversed() to sort...
When you need to sort a collection in descending order, the java reverseorder comparator is the standard tool. Java provides several ways to reverse the natural order of a comparator, and the right choice depends on whether you are sorting objects with a natural order, using an existing comparator, or working with custom objects.
What Is a Reverse-Order Comparator?
A comparator defines an ordering by returning a negative integer, zero, or a positive integer when comparing two objects. Reversing a comparator swaps the sign of that result, so the order is inverted. In Java, you can obtain a reverse-order comparator for any Comparable type using Comparator.reverseOrder() or Collections.reverseOrder(). Both return a comparator that imposes the reverse of the natural ordering. For example, the natural order of integers is ascending, so the reverse-order comparator sorts them descending.
Using Comparator.reverseOrder() for Natural Ordering
The simplest way to sort a list in descending order is to pass Comparator.reverseOrder() to the sort method. This works for any class that implements Comparable, such as String, Integer, LocalDate, and your own types if they define compareTo.
List<String> names = new ArrayList<>(List.of("Alice", "Bob", "Charlie")); names.sort(Comparator.reverseOrder()); System.out.println(names); // [Charlie, Bob, Alice]
The comparator returned by reverseOrder() is stateless and can be reused across multiple sorts. It also works with the List.sort method introduced in Java 8, which is the preferred way to sort a list in place.
Using Collections.reverseOrder() as an Alternative
Before Comparator was enhanced in Java 8, Collections.reverseOrder() was the standard way to get a reverse natural ordering comparator. It still exists and behaves identically to Comparator.reverseOrder(). Both return a comparator that is serializable. You might encounter Collections.reverseOrder() in legacy code or when working with APIs that expect a Comparator from the java.util package.
List<Integer> numbers = new ArrayList<>(List.of(5, 2, 8, 1)); Collections.sort(numbers, Collections.reverseOrder()); System.out.println(numbers); // [8, 5, 2, 1]
While both are functionally equivalent, Comparator.reverseOrder() is more idiomatic in modern Java because it keeps your code consistent with the Comparator interface and its default methods.
Reversing an Existing Comparator with Comparator.reversed()
When you have a custom comparator, you can reverse it by calling the reversed() default method. This is particularly useful when you define a comparator using Comparator.comparing or a lambda and then need the opposite order without rewriting the logic.
class Person { String name; int age; // constructor, getters, toString omitted } Comparator<Person> byAge = Comparator.comparing(Person::getAge); List<Person> people = getPeople(); people.sort(byAge.reversed());
The reversed() method returns a new comparator that applies the original comparator's logic but with the result negated. The original comparator remains unchanged, so you can use both orders in the same scope without recreating anything.
Sorting Streams in Reverse Order
Streams also support sorting with a comparator. You can use Stream.sorted(Comparator.reverseOrder()) for natural ordering, or apply reversed() to a custom comparator. The stream pipeline collects the result into a new collection, leaving the source unchanged.
List<String> sortedDesc = list.stream() .sorted(Comparator.reverseOrder()) .collect(Collectors.toList());
For custom objects, the same pattern applies:
List<Person> sortedByAgeDesc = people.stream() .sorted(Comparator.comparing(Person::getAge).reversed()) .collect(Collectors.toList());
Keep in mind that sorted() on a stream does not modify the original list. If you need the sorted result in place, use List.sort instead.
Handling Null Values and Edge Cases
Neither Comparator.reverseOrder() nor Collections.reverseOrder() handles null elements. If your list contains nulls, calling sort with these comparators will throw NullPointerException because compareTo is invoked on a null reference. To handle nulls, combine the reverse-order comparator with Comparator.nullsFirst or Comparator.nullsLast. The key is to apply the null-handling comparator first and then reverse the combined result if needed.
For example, to sort a list of strings with nulls placed last and non-null strings in descending order:
Comparator<String> nullsLastDesc = Comparator.nullsLast(Comparator.reverseOrder()); list.sort(nullsLastDesc);
If you want nulls first and then descending order, you need to reverse a comparator that puts nulls first:
Comparator<String> nullsFirstDesc = Comparator.nullsFirst(Comparator.naturalOrder()).reversed();
This works because reversed() flips the entire ordering, including the placement of nulls. Always test such combinations with your actual data to confirm the null placement matches your requirements.
Performance and Maintainability Considerations
Reversing a comparator is a cheap operation. The reversed() method simply returns a comparator that negates the result of the original comparison, so there is no significant runtime cost or extra memory allocation. Both Comparator.reverseOrder() and Collections.reverseOrder() return singletons, so they are also efficient.
From a maintainability perspective, prefer Comparator.comparing with method references over anonymous inner classes. This makes the comparator logic explicit and easier to reverse. For example, Comparator.comparing(Person::getAge).reversed() is clearer than writing a custom compare method that manually reverses the order. Also, be aware that reversing a comparator that has complex logic (e.g., chained comparisons with thenComparing) reverses the entire chain, not just the primary key. If you need to reverse only one key in a multi-key comparator, you must reverse that key's comparator before chaining.
Choosing the Right Reverse-Order Approach
The table below summarizes when to use each method:
| Scenario | Recommended Approach |
|---|---|
Natural ordering of Comparable types | Comparator.reverseOrder() |
Legacy code or APIs using Collections | Collections.reverseOrder() |
| Reversing a custom comparator | Comparator.reversed() on the existing comparator |
| Sorting a stream in descending order | Stream.sorted(Comparator.reverseOrder()) or Comparator.comparing(...).reversed() |
| Handling nulls in descending order | Comparator.nullsLast(Comparator.reverseOrder()) or Comparator.nullsFirst(...).reversed() |
For primitive arrays, you cannot use Comparator directly. Convert the array to a boxed stream, sort, and convert back, or use a library like Arrays.sort with a custom comparator after boxing. The Comparator.reverseOrder() method is available since Java 8, while Collections.reverseOrder() has existed since Java 1.2, so compatibility is rarely a concern.
When you need descending order, the java reverseorder comparator is the direct solution. Whether you use the built-in natural reversal or flip a custom comparator, the approach is straightforward and integrates cleanly with lists, streams, and the Collections framework.