比较方法违反了使用日期的一般合同例外

问题描述 投票:0回答:2

我在下面使用一个简单的比较器按比赛的开始时间进行排序,但是即使我涵盖了所有可能性,也会收到错误消息“比较方法违反了其一般合同”。对我所缺少的内容有任何帮助吗?

    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;
        }
    });
java sorting collections comparator
2个回答
0
投票

如果您在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

0
投票

我看不到它返回0的任何情况。进一步查看时,我发现比较2个具有相同开始时间的对象的返回值为1。因此,违反了以下合同规则:

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

如果x和y具有相同的开始时间。 sgn(1)!= -sgn(1)。在这种情况下,该方法必须返回0。

© www.soinside.com 2019 - 2024. All rights reserved.