Ошибка «Метод сравнения нарушает общий договор» при сравнении Date с помощью before () - PullRequest
1 голос
/ 29 мая 2020

Я использовал list.sort(), чтобы отсортировать список объектов с типом Date, и получил java .lang.IllegalArgumentException: метод сравнения нарушает его общий контракт! Меня это довольно смущает ошибка.

Код, показанный ниже

List<Date> list = new ArrayList<>(200);

Date now = new Date();
for (int i = 0; i < 200; ++i) {
    int delta = ThreadLocalRandom.current().nextInt(2, 10);
    list.add(DateUtils.addMinutes(now, delta));
}

list.sort((x, y) ->  {
    int cmp = x.before(y) ? -1 : 1;
    return cmp;
});

Я искал в Google и обнаружил много похожих проблем (Java ошибка: метод сравнения нарушает общий договор ), которые говорят о том, что компаратор не соответствует правилу транзитивности. Однако кажется, что Date.before должно следовать правилу транзитивности.

И я знаю, что у компаратора есть проблема при сравнении двух одинаковых дат. Для любых двух одинаковых дат, скажем, d1, d2, оба cmp(d1, d2) и cmp(d2, d1) возвращают 1.

Однако, если мы заменяем компаратор, всегда возвращаем 1, ошибка не выводится. Как удивительно!

list.sort((x, y) -> 1);

В приведенном выше примере я создал дублированную дату лотов, которая использовалась для воспроизведения ошибки. Несмотря на то, что я знаю, как решить эту проблему, я все же хочу знать, почему использование before() даст сбой.

Между прочим, я тестировал его на JDK 8 и 11, оба отказались.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...