Метод сравнения нарушает свое исключение из общего контракта с использованием даты - PullRequest
1 голос
/ 20 января 2020

Я использую простой компаратор ниже для сортировки по времени начала конкурса, но получаю сообщение об ошибке «Метод сравнения нарушает его общий контракт», хотя я рассмотрел все возможности. Любая помощь в том, что мне не хватает?

    Collections.sort(contests, new Comparator<Contest>() {
        @Override
        public int compare(Contest o1, Contest o2) {
            if (o1.getStartTime() != null && o2.getStartTime() != null) {
                if (o1.getStartTime().getTime() < o2.getStartTime().getTime()) {
                    return -1;
                }
                return 1;
            } 
            return 1;
        }
    });

Ответы [ 2 ]

2 голосов
/ 20 января 2020

Я не вижу ни одного случая, когда он возвращает 0. И при взгляде дальше я вижу, что возвращаемое значение, когда сравниваются 2 объекта, которые имеют одинаковое время начала, будет 1. И из-за этого следующее правило контракта нарушается:

sgn(compare(x, y)) == -sgn(compare(y, x)) 

Если x и y имеют одинаковое время начала. sgn (1)! = -sgn (1). В этом случае метод должен вернуть 0.

0 голосов
/ 20 января 2020

Если вы работаете на Java 8, вы можете использовать:

List<Contest> sorted = contests.stream()
            .sorted(Comparator.comparing(contest -> contest.getStartTime().getTime(), Comparator.nullsFirst(Comparator.naturalOrder())))
            .collect(Collectors.toList());

Не зная подробностей о вашем типе данных startTime, предполагая, что time математически сопоставимо с вашим кодом, полнота кода приведена ниже. , Отрегулируйте в соответствии с вашими потребностями.

class Sorting {
    public static void main(String[] args) {
        List<Contest> contests = new ArrayList<>();

        contests.add(new Contest(new TimeHolder(1)));
        contests.add(new Contest(new TimeHolder(3)));
        contests.add(new Contest(new TimeHolder(2)));
        List<Contest> sorted = contests.stream()
            .sorted(Comparator.comparing(contest -> contest.getStartTime().getTime(), Comparator.nullsFirst(Comparator.naturalOrder())))
            .collect(Collectors.toList());

        sorted.forEach(contest -> System.out.println(contest.getStartTime().getTime()));
    }

    static class Contest {
        TimeHolder startTime;

        public Contest(TimeHolder startTime) {
            this.startTime = startTime;
        }

        public TimeHolder getStartTime() {
            return startTime;
        }
    }
    static class TimeHolder{
        int time;

        public TimeHolder(int time) {
            this.time = time;
        }

        public int getTime() {
            return time;
        }
    }
}

Выход:

1
2
3
...