One of my applications once threw an IllegalArgumentException stating that the Comparison method violates its general contract. I've found some sources detailing the problem like https://bugs.java.com/bugdatabase/view_bug?bug_id=6804124 and http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#source and wanted to fix this in my application.
But I can not reproduce the problem hence can not know if my fix is correct.
In my efforts to reproduce, I tried to simplify the problem as much as possible and came up with a little class that looks like this:
public class Sortee implements Comparable<Sortee>
{
/** a value to sort by */
public final int _x;
public Sortee(int x)
{
_x = x;
}
public int compareTo(Sortee o)
{
return 1;
}
}
I've also created an equivalent as Comparator:
public class SorteeIncorrectComparator implements Comparator<Sortee>
{
public int compare(Sortee a, Sortee b)
{
return 1;
}
}
In another class I created a List of Sortee objects and called the Collections.sort() variants to provoke the IllegalStateException:
private static void sort()
{
List<Sortee> sortees = createSortees();
Collections.shuffle( sortees );
Collections.sort( sortees, new SorteeIncorrectComparator() );
Collections.shuffle( sortees );
Collections.sort( sortees );
}
But the IllegalStateException is never raised.
I've tried it on Linux and Windows and in eclipse on Windows with Java 1.7.0_21, 23.21-b01 and checked that property java.util.Arrays.useLegacyMergeSort is not set.
I thought that always returning 1 in the compare method should break the contract, as it is neither commutative nor transitive.
Why do I never get an IllegalStateException?
My implementation actually was transitive.
I've changed the compare method to return random values and that raises the Exception.