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

另一个“比较法违反了一般合同!”

秋建义
2023-03-14

作为实习的一部分,我被要求调查一个错误。一段代码正在抛出

Java . lang . illegalargumentexception:比较法违反了它的通用契约!

自定义比较器通过查看自定义类的Long成员变量来比较两个自定义类:

return v1 > v2 ? -1 : v1 < v2 ? 1 : 0;

此自定义类的 equals 方法查看此自定义类的 String 成员变量。我们很难重现这种行为。我的下意识反应是将自定义比较器中的 return 语句替换为 return v2.compareTo(v1);,但我的团队怀疑这会解决问题。谁能提供任何见解?

Arrays.sort(anArray, new Comparator<ACustomClass>() {
  @Override
  public int compare(ACustomClass o1, ACustomClass o2) {
    long v1 = o1.getALong();
    long v2 = o2.getALong();
    return v1 > v2 ? -1 : v1 < v2 ? 1 : 0;
  }});

共有2个答案

沈枫涟
2023-03-14

我认为你在这里找错了地方。这段代码不会引发异常。我想看看堆栈跟踪,我也想看看ACustomClass.equals()方法。除非它测试getOn()结果是否相等,否则它不同意这个比较器,因此其中一个是错误的,如果在需要与等于一致的上下文中使用,例如排序集合,这更有可能是异常产生的地方。

你可以通过实验来解决这种怀疑。除非他们能提出一个实际的正式理由,为什么它不能工作,否则你当然有权尝试。

喻嘉泽
2023-03-14

我看不出所提出的比较器有什么明显的问题。(我对提议的修正持怀疑态度:它们对我来说有伏都教编程的“味道”。)

但如果ACustomClass类的aLong属性是可变的…并且在排序时发生了更改…那么这可能会导致排序代码认为比较器违反了约定。

所以……检查这是否可能是并发问题,其中一个线程正在改变另一个线程试图排序的数组中的对象。

我们花了很多时间在调试器上...许多不同的测试用例。无法重现该行为。

我会将其视为指向并发问题的证据。。。

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

  • 下面的代码是Dave Koelle的AlphanumComparator的编辑版本。编辑包含将空字符串排序到列表末尾或 底部的代码。问题是 为了解决我的问题,我调查了它并找到了诸如比较器没有 等原因; 在正确的位置。我还在Java错误数据库中发现了一条评论,上面写着 java.util.Arrays.sort和java.util.Collections.sort(间接地)使用的排序算法被替换了,新

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

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

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

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