Одно из моих приложений однажды выдало исключение IllegalArgumentException, в котором говорилось, что метод Comparison нарушает его общий контракт. Я нашел несколько источников с подробным описанием проблемы, таких как http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6804124 и http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#source и хотел исправить это в своем приложении.
Но я не могу воспроизвести проблему, поэтому не могу знать, правильно ли мое исправление.
Пытаясь воспроизвести, я попытался максимально упростить задачу и придумал небольшой класс, который выглядит так:
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;
}
}
Я также создал эквивалент в качестве компаратора:
public class SorteeIncorrectComparator implements Comparator<Sortee>
{
public int compare(Sortee a, Sortee b)
{
return 1;
}
}
В другом классе я создал объекты List of Sortee и вызвал варианты Collections.sort(), чтобы спровоцировать исключение IllegalStateException:
private static void sort()
{
List<Sortee> sortees = createSortees();
Collections.shuffle( sortees );
Collections.sort( sortees, new SorteeIncorrectComparator() );
Collections.shuffle( sortees );
Collections.sort( sortees );
}
Но исключение IllegalStateException никогда не возникает.
Я пробовал это в Linux и Windows, а также в eclipse в Windows с Java 1.7.0_21, 23.21-b01 и проверил, что свойство java.util.Arrays.useLegacyMergeSort не установлено.
Я думал, что всегда возвращать 1 в методе сравнения должно нарушать контракт, поскольку он не является ни коммутативным, ни транзитивным.
Почему я никогда не получаю исключение IllegalStateException?