Java8中两种Comparator反向排序写法为何结果一致?
Great question! Let's break down exactly what's happening with each comparator to see why they end up producing the same result.
First, let's restate the two code snippets clearly:
- Snippet 1:
Comparator.comparing(SortedClass::getValue).thenComparing(SortedClass::getKey, reverseOrder()); - Snippet 2:
Comparator.comparing(SortedClass::getValue).reversed().thenComparing(SortedClass::getKey).reversed();
Let's Unpack Snippet 1 First
This one's straightforward:
- First, it sorts ascending by
getValue()(the default behavior ofcomparing()). - When two items have the same
Value, it sorts descending bygetKey()(explicitly usingreverseOrder()to flip the default ascending sort for keys).
Now Let's Step Through Snippet 2
Let's build this comparator piece by piece to see how the two reversed() calls interact to match Snippet 1:
- Start with a base comparator:
Comparator.comparing(SortedClass::getValue)→ sorts ascending byValue. - Add
.reversed()→ this flips the base logic, so now we sort descending byValue. - Add
.thenComparing(SortedClass::getKey)→ the full logic becomes: sort descending byValue, and for ties, sort ascending byKey. - Add the final
.reversed()→ this flips the entire compound comparator's logic, not just individual parts.
Here's the critical insight: reversing a compound comparator (like A.thenComparing(B)) inverts the entire comparison workflow. Let's translate what the final reversed comparator does:
- Instead of checking "is o1's Value greater than o2's Value?" (for descending order), it now checks the opposite: "is o2's Value greater than o1's Value?" → which is exactly equivalent to sorting ascending by
Value(matching Snippet 1's first step). - For ties where Values are equal, instead of checking "is o1's Key greater than o2's Key?" (for ascending order), it checks "is o2's Key greater than o1's Key?" → which is equivalent to sorting descending by
Key(matching Snippet 1's second step).
In Short
The two reversed() calls in Snippet 2 effectively "undo" each other's impact on the primary sort, but combine to flip the secondary sort—resulting in exactly the same logic as Snippet 1. It's like reversing a list twice: you end up back where you started for the main order, but the secondary order gets flipped once (which aligns with the explicit reverseOrder() in Snippet 1).
内容的提问来源于stack exchange,提问作者Santanu Sahoo

