Reputation: 155
Below is a block of code that results in exception as indicated,
Code :
Collections.sort( arrayList, new Comparator()
{
public int compare( Object o1, Object o2 )
{
TypeAdapterSort tas1 = ( TypeAdapterSort ) o1;
TypeAdapterSort tas2 = ( TypeAdapterSort ) o2;
if ( tas1.order < tas2.order )
return -1;
else
return 1;
}
} );
Exception :
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.mergeForceCollapse(TimSort.java:426)
at java.util.TimSort.sort(TimSort.java:223)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
When I run the same code as a standalone program, the issue never occurs. What is the issue with the comparator here? Is there a way to reproduce the issue in a standalone code?
This issue occurs only on Java 1.7 as there has been change in the implementation on Arrays.sort & Collections.sort. How to change the above code to avoid the issue?. Also, how to reproduce this issue in a standalone code?
Upvotes: 3
Views: 7907
Reputation: 31
In your comparator, for A == B, compare(A,B) returns 1 (A>B), but compare(B,A) still returns 1 (meaning B>A). If the sorting algorithm detects this contradiction, it throws an exception instead of maybe endlessly looping or recursing.
Upvotes: -1
Reputation: 19294
You need to return 0 on equal objects.
if ( tas1.order < tas2.order ){
return -1;
} else if ( tas1.order == tas2.order ){
return 0;
} else {
return 1;
}
You can read here more
Upvotes: 3