另一种“比较方法违反了其总合同!”

时间:2013-08-07 23:30:09

标签: java java-7 comparator illegalargumentexception

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

  

java.lang.IllegalArgumentException:比较方法违反了其一般合同!

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

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

此自定义类的equals方法查看此自定义类的String成员变量。 我们有一段时间重现这种行为。 我的下意识反应是用Comparator替换自定义return v2.compareTo(v1);中的return语句, 但是我的团队怀疑这会解决这个问题。 任何人都可以提供任何见解吗?

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

答案 0 :(得分:6)

我看不出比较器出现的明显错误。 (我对提议的修正案持怀疑态度:他们“嗅到”伏都教编程给我。)

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

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


  

我们花了很多时间在这个调试器上......很多不同的测试用例。无法获得要复制的行为。

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

答案 1 :(得分:0)

我认为你在这里咆哮着错误的树。那段代码不会抛出异常。我希望看到一个堆栈跟踪,我也会看到ACustomClass.equals()方法。除非它测试getAlong()结果是否相等,而没有别的,它不同意这个Comparator,,因此其中一个是错误的,如果在上下文中使用需要与equals的一致性,例如排序集合,这更可能是异常产生的地方。

您可以通过实验解决怀疑论。除非他们能够提出一个无法正常工作的正式理由,否则你肯定有权尝试。