Reputation: 39
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:747)
at java.util.TimSort.mergeAt(TimSort.java:483)
at java.util.TimSort.mergeCollapse(TimSort.java:408)
at java.util.TimSort.sort(TimSort.java:214)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
Can someone explain why my comparator below sometimes throws the above exception.
Note: The id field in myObject is of type long.
Collections.sort(objectList, new Comparator<MyObject>() {
@Override
public int compare(final myObject myobject1, final MyObject myObject2) {
return (int)(myObject1.getId() - myObject2.getId());
}
});
Solution:
Based on the answer from @amit
return (int)(Long.compare(myObject1.getId(), myObject2.getId());
Upvotes: 0
Views: 2785
Reputation: 178481
You might encounter an integer overflow if the ID is relatively high integers in absolute values, which will cause VERY_HIGH_INT - VERY_LOW_INT
to be a negative number. This is obviously wrong, and is breaking the contract of the comparator.
Use Integer.compare()
(or similarly Long.compare()
, Double.compare()
...) rather than substracting numbers to avoid it.
EDIT:
Specifically here, the problem is still integer overflow, when casting a long value where its 32 LSbs are in range [2^31,2^32) from long
to int
, which causes it to be erroneously negative. Demo in ideone.
Solution is the same. Use Long.compare()
Upvotes: 4
Reputation: 23354
Java 7
has changed the default sort algorithm from MergeSort
to TimSort
in the java.util.Arrays.sort
method.
The sorting algorithm used by java.util.Arrays.sort
and (indirectly
) by java.util.Collections.sort
has been replaced. The new sort implementation may throw an IllegalArgumentException
if it detects a Comparable that violates the Comparable contract.
For backward compatibility and to restore the behavior from Java version 6, add new system property- java.util.Arrays.useLegacyMergeSort.
Refer the following link for details -
http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#source
Upvotes: 0