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

Метод сравнения нарушает его общий контракт в Java 7

Я получаю "Метод сравнения нарушает его общий контракт" после компиляции некоторого кода Java в Java 7 и затем его запуска.

Я прочитал Метод сравнения нарушает общий контракт! Java 7 только и понять, что с моим кодом, который был проигнорирован в предыдущих версиях Java, что-то не так. Однако я не могу понять, что не так с моим кодом. Команда Collections.sort() генерирует ошибку.

Мой код:

   public Comparator sortBySmoothDays() {
    Comparator c = new Comparator() {
        public int compare(Object arg0, Object arg1) {
            Date date0 = ((PosObject)arg0).getDate();
            Date date1 = ((PosObject)arg1).getDate();

            double d1 = MyUtils.calcSmoothDays(date0, new Date());
            double d2 = MyUtils.calcSmoothDays(date1, new Date());
            if (d1 >= d2) {
                return 1;
            }
            else {
                return -1;
            }   
        }
    };
    return c;
}


Comparator c = ComparatorUtils.getInstance().sortBySmoothDays();
Collections.sort(posList, c);

Может ли кто-нибудь помочь? Спасибо!

4b9b3361

Ответ 1

Компаратор должен возвращать 0, если значения равны. В вашей текущей реализации вы возвращаете 1, если они равны. Самый простой способ правильно сравнить ваши значения double - это вызвать Double.compare:

double d1 = MyUtils.calcSmoothDays(date0, new Date());
double d2 = MyUtils.calcSmoothDays(date1, new Date());

return Double.compare(d1, d2);

Ответ 2

С вашим компаратором каждый объект сравнивается больше, чем он сам: compare(x,x) всегда возвращает один.

Это нарушает следующее требование:

Разработчик должен гарантировать, что sgn (compare (x, y)) == -sgn (compare (y, x)) для всех x и y.

Из приведенного выше требования следует, что compare(x,x) должен возвращать ноль.

Я бы рекомендовал прочитать контракт и убедиться, что ваша реализация соответствует ему.

В частности, если date0.equals(date1), компаратор, вероятно, должен сразу же вернуть нуль, не делая никаких преобразований с плавающей запятой и сравнений.

Ответ 3

Не исключено, что если два объекта сравниваются равными, т.е. calcSmoothDays возвращает одно и то же значение, тогда у вас может быть ситуация, когда compare (object1, object2) == 1 и compare (object2, object1) == 1 также?

Итак, это означает, что object1 > object 2 и object2 > object 1...