Подтвердить что ты не робот

Почему мой метод сравнения исключает исключение - метод сравнения нарушает общий контракт!

Почему этот код

public class SponsoredComparator implements Comparator<SRE> {

    public boolean equals(SRE arg0, SRE arg1){
        return arg0.getSponsored()==arg1.getSponsored();
    }

    public int compare(SRE object1, SRE object2) {
        Log.d("SponsoredComparator","object1.getName() == "+ object1.getName());
        Log.d("SponsoredComparator","object1.getSponsored() == "+ object1.getSponsored());
        Log.d("SponsoredComparator","object2.getName() == "+ object2.getName());
        Log.d("SponsoredComparator","object2.getSponsored() == "+ object2.getSponsored());
        Log.d("SponsoredComparator","compare return == "+ (object1.getSponsored() && object2.getSponsored() ? 0 : object1.getSponsored() ? -1 : 1));
        return object1.getSponsored() && object2.getSponsored() ? 0 : object1.getSponsored() ? -1 : 1;
    }
}

выбросить это исключение: ERROR/AndroidRuntime(244): java.lang.IllegalArgumentException: Comparison method violates its general contract!
ERROR/AndroidRuntime(4446): at java.util.TimSort.mergeLo(TimSort.java:743)

Метод sre.getSponsored() возвращает логическое значение.

Спасибо.

4b9b3361

Ответ 1

Я подозреваю, что проблема возникает, когда ни одно значение не спонсируется. Это вернет 1, как вы его называете, т.е.

x1.compare(x2) == 1

x2.compare(x1) == 1

Это неверно.

Я предлагаю вам изменить это:

object1.getSponsored() && object2.getSponsored()

к

object1.getSponsored() == object2.getSponsored()

в обоих местах. Вероятно, я, вероятно, извлечу этот метод с такой сигнатурой где-нибудь:

public static int compare(boolean x, boolean y)

а затем вызовите его следующим образом:

public int compare(SRE object1, SRE object2) {
    return BooleanHelper.compare(object1.getSponsored(), object2.getSponsored());
}

Это сделает код более понятным, IMO.

Ответ 2

Я предполагаю, что вы используете JDK 7. Проверьте следующий URL:

От http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#source

Область: API: Утилиты

Сводка: обновленное поведение сортировки для Arrays и Collections может a IllegalArgumentException

Описание: алгоритм сортировки, используемый java.util.Arrays.sort и (косвенно) на java.util.Collections.sort. Новый сортировка может вызывать IllegalArgumentException, если он обнаруживает a Comparable, который нарушает контракт Comparable. Предыдущий реализация молча игнорировала такую ​​ситуацию. Если предыдущий поведение желательно, вы можете использовать новую систему свойство, java.util.Arrays.useLegacyMergeSort, чтобы восстановить предыдущий mergesort.

Характер несовместимости: поведенческий

RFE: 6804124

Для получения более подробной информации см. базу данных ошибок ссылка здесь.

Ответ 3

Договор между equals() и compareTo() заключается в том, что когда equals() возвращает true, compareTo() должен возвращать 0 и когда equals() является false, compareTo должен возвращать -1 или +1.

BTW: Я предполагаю, что ваш метод compare() не вызывается очень часто, так как отладочные сообщения будут использовать знаковое количество CPU и памяти.

Ответ 4

Я согласился со всем ответом специально с jon, но одним дополнением я хочу сказать, что мы всегда должны проверять нулевую безопасность в методе сравнения, чтобы наш метод никогда не прерывался, и это хорошая привычка в программировании для всегда нулевой проверки. Для получения дополнительной информации смотрите здесь

Ответ 5

Возможно, у вас есть значения NaN, которые вы сравниваете с помощью Collections.sort... это было проблемой для меня, и я получил это исключение, даже имея правильную реализацию метода сравнения (obj1, obj2)! Проверьте это!

Ответ 6

У меня такая же проблема сегодня в веб-приложении. Четыре вызова, работающие над одним и тем же массивом, пытались сортировать их в одно и то же время, эффективно испортив друг друга.

Ответ 7

Мое решение: когда я хочу отсортировать числа и элемент массива равен нулю, я ставлю 0, тогда ошибка исчезает. Необходимо позаботиться о том, чтобы размеры каждой строки в двумерных массивах были одинаковыми.