I got the following exception, and I don’t quite understand why:
java.lang.IllegalArgumentException: the comparison method violates the general contract!
in java.util.TimSort.mergeLo (TimSort.java:777) in java.util.TimSort.mergeAt (TimSort.java∗14) at java.util.TimSort.mergeCollapse (TimSort.java:441) at java.util. TimSort.sort (TimSort.java:245) in java.util.Arrays.sort (Arrays.java:1512) in java.util.ArrayList.sort (ArrayList.java:1454)
I wrote the following JUnit test to test the behavior:
@Test
public void testComparator() {
    List<Boolean> item = new ArrayList<>();
    item.add(true);
    for (int i = 0; i < 1000000; i++) {
        item.add(false);
    }
    while(true) {
        System.out.println("Sorting");
        Collections.shuffle(item);
        item.sort((lineItem1, lineItem2) -> {
            if (lineItem1 && lineItem2) {
                return 0;
            } else if (!lineItem1) {
                return 1; 
            } else if (!lineItem2 ) {
                return -1;
            } 
            return 0;
        });
    }
}
If I change return 1 and return -1, it suddenly works without exception. But why? This should only change the sort order and not break the entire comparator.
What am I missing?
source
share