当前位置: 首页 > 知识库问答 >
问题:

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

严修德
2023-03-14

我在下面使用一个简单的比较器来按比赛的开始时间进行排序,但是我得到了错误“比较方法违反了它的一般合同”,尽管我涵盖了所有的可能性。对我缺少什么有任何帮助吗?

    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个答案

贺靖
2023-03-14

如果您运行的是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
鞠宏恺
2023-03-14

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

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

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

 类似资料:
  • 下面是导致异常的代码块,如所示, 代码: 例外情况: 当我将相同的代码作为独立程序运行时,该问题从未出现。这里的比较器有什么问题?有没有办法在独立代码中重现该问题? 这个问题只在Java 1.7上出现,因为Arrays.sort上的实现发生了变化

  • 我在尝试对节点的数组列表进行排序时遇到了这个错误。我尝试了大多数解决方案,但没有一个在我的案例中有效。 此代码为 它适用于小输入,但是当输入数量很大时,它会给出这个错误。我也读过比较方法中的传递性规则,但我不知道它是如何在这种情况下应用的。 先谢谢你。

  • 我有一个类字段,和。我需要使用对它们进行排序,但我得到了一个异常: java.lang.IllegalArgumentException:比较方法违反了它的一般约定! 我的< code>compareTo方法: 请帮我找出compareTo方法中的错误。谢了。

  • 我目前正在Java中对集合进行排序。我收到了错误消息“比较方法违反了它的一般契约”。我也理解这个错误消息,但我(主要)使用Long类型的构建比较方法。所以我不知道,在这种情况下,排序方法仍然违反了契约。这是我的代码: 这里是错误:

  • 我看到我的应用程序在一些中国 Android 手机上发生了很多崩溃,并出现错误:比较方法违反了其总合同! 我读过这与Collections.sort有关。 我不太确定的是,这是否是因为我的自定义比较器。 以下是错误发生的地方: 比较器是这样的: 所以我不太确定比较器是否搞砸了什么,或者我是否需要以不同的方式进行collections.sort调用 感谢任何帮助

  • 我正在将我们的项目升级到java 7。我遇到了Collections.sort()的非法参数异常。我知道这个异常的原因是java 7中新的Timsort(我确实抛出了之前在这个问题上提出的所有问题)。现在我需要修改比较逻辑来克服这个异常。这是我的比较方法 > < li> 我尝试覆盖equals()方法,使用与compare相同的逻辑,认为如果equals和compare返回相同的结果,应该可以解决