【问题标题】:Comparison Method violates its general contract in Java 7比较方法违反了它在 Java 7 中的一般约定
【发布时间】:2012-02-28 17:18:41
【问题描述】:

在 Java 7 中编译一些 Java 代码然后运行它后,我收到“比较方法违反其一般合同”。

我已阅读Comparison method violates its general contract! Java 7 only 并意识到我的代码有问题,在以前的 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);

有人可以帮忙吗?谢谢!

【问题讨论】:

  • JFI:抛出这个异常是 Java7 的一个新特性。可以使用新的系统属性配置旧行为:java.util.Arrays.useLegacyMergeSort 请参阅stackoverflow.com/a/8417446/450812

标签: java


【解决方案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);

【讨论】:

  • 它返回 1,而不是 -1。
  • @Boann 因为 3.5 年前,我很愚蠢 :)。随意编辑答案。
【解决方案2】:

使用您的比较器,每个对象的比较都大于自身:compare(x,x) 总是返回一个。

这违反了以下requirement

实施者必须确保所有 x 和 y 的 sgn(compare(x, y)) == -sgn(compare(y, x))。

上述要求意味着compare(x,x) 必须返回零。

我建议阅读contract 并确保您的实现能够满足它。

特别是,如果date0.equals(date1),比较器可能应该立即返回零,而不进行任何浮点转换和比较。

【讨论】:

  • 更一般地说,使用这种方法没有两个对象可以彼此相等。没有产生 0(或等于)结果的代码路径。
【解决方案3】:

如果两个对象比较相等,即 calcSmoothDays 返回相同的值,那么您可能会遇到 compare(object1,object2) == 1 和 compare (object2,object1) == 1 的情况?

p>

所以这意味着 object1 > object 2 和 object2 > object 1...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多