1

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

java.lang.IllegalArgumentException:比较方法违反了它的一般约定!

自定义通过查看所述自定义类的成员变量Comparator来比较两个自定义类:long

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

此自定义类的equals方法查看此自定义类的String成员变量。我们在重现这种行为时遇到了麻烦。我的下意识反应是将自定义中的 return 语句替换为Comparatorreturn 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;
  }});
4

2 回答 2

6

我看不出所呈现的比较器有任何明显错误。(而且我对提议的修复持怀疑态度:它们对我来说是伏都教编程的“气味”。)

但是如果ACustomClass类的aLong属性是可变的......并且在您排序时它发生了变化......那么这可能会导致排序代码认为比较器违反了合同。

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


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

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

于 2013-08-08T00:42:33.110 回答
0

我想你在这里叫错树了。那段代码不会抛出该异常。我想看一个堆栈跟踪,我也会看这个ACustomClass.equals()方法。除非它测试getAlong()结果是否相等,否则它不同意这一点Comparator,,因此其中一个是错误的,如果在需要与 equals 保持一致的上下文中使用,例如排序集合,这更可能是异常产生于。

您可以通过实验解决怀疑。除非他们能提出一个实际的正式原因,否则你当然有权尝试它。

于 2013-08-08T00:01:40.360 回答