Card 07/ 09
All 9 cards
GotchaDifficulty: Advanced1 min
Why Your Sort Threw Comparison Method Violates Its General Contract
A sort that has always worked throws, on a particular list, with a message about a contract nobody remembers agreeing to. The same comparator on a shorter list is fine.
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!Java's sort assumes the comparator is consistent, and it checks that assumption while it works. Three things have to hold for every pair and triple it is given.
| Rule | Means |
|---|---|
| Antisymmetry | If compare(a, b) is negative, compare(b, a) is positive |
| Transitivity | If a is before b and b is before c, then a is before c |
| Consistent ties | If a and b tie, they compare the same way against every c |
The two usual causes are the overflow from subtracting, and a comparator that returns zero for pairs it cannot decide between while ordering them differently through some other route. Both break transitivity, and neither shows up until the sort happens to compare the offending triple.
Build comparators from Comparator.comparing and thenComparing rather than writing the arithmetic. Those combinators are consistent by construction, and the contract stops being something you have to remember.