我被要求调查一个错误,作为我实习的一部分。 一段代码正在抛出
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;
}});
答案 0 :(得分:6)
我看不出比较器出现的明显错误。 (我对提议的修正案持怀疑态度:他们“嗅到”伏都教编程给我。)
但是如果ACustomClass
类的aLong
属性是可变的...... 并且在您排序时发生了变化 ...那么这可能导致排序代码认为比较国违反了合同。
所以...检查这是否是一个并发问题,其中一个线程正在改变另一个线程试图排序的数组中的对象。
我们花了很多时间在这个调试器上......很多不同的测试用例。无法获得要复制的行为。
我会将其视为指向并发问题的证据......
答案 1 :(得分:0)
我认为你在这里咆哮着错误的树。那段代码不会抛出异常。我希望看到一个堆栈跟踪,我也会看到ACustomClass.equals()
方法。除非它测试getAlong()
结果是否相等,而没有别的,它不同意这个Comparator,
,因此其中一个是错误的,如果在上下文中使用需要与equals的一致性,例如排序集合,这更可能是异常产生的地方。
您可以通过实验解决怀疑论。除非他们能够提出一个无法正常工作的正式理由,否则你肯定有权尝试。