下面是一个导致异常的代码块,
代码:
Collections.sort( arrayList, new Comparator()
{
public int compare( Object o1, Object o2 )
{
TypeAdapterSort tas1 = ( TypeAdapterSort ) o1;
TypeAdapterSort tas2 = ( TypeAdapterSort ) o2;
if ( tas1.order < tas2.order )
return -1;
else
return 1;
}
} );
例外:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:747)
at java.util.TimSort.mergeAt(TimSort.java:483)
at java.util.TimSort.mergeForceCollapse(TimSort.java:426)
at java.util.TimSort.sort(TimSort.java:223)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
当我运行与独立程序相同的代码时,问题永远不会发生。 这里的比较器有什么问题? 有没有办法在独立代码中重现问题?
此问题仅在Java 1.7上发生,因为Arrays.sort&amp;的实现已发生变化。 Collections.sort。如何更改上面的代码以避免问题?另外,如何在独立代码中重现此问题?
答案 0 :(得分:4)
比较器不遵守一般合约。看看这个:
if ( tas1.order < tas2.order )
return -1;
else
return 1;
}
现在考虑两个具有相同order
的对象。比较它们应该返回0。
如果您使用的是Java 7,那么最好委托给Integer.compare
:
return Integer.compare(tas1.order, tas2.order);
或者,如果您使用的是早期版本:
return tas1.order == tas2.order ? 0
: tas1.order < tas2.order ? -1
: 1;
答案 1 :(得分:1)
您不需要仅返回-1或1.一般合同规定如果第一个元素较小则返回的数字必须为负数,如果它们相等则为零,如果第二个元素较小则返回正数。所以你可以跳过if / else语句然后返回:
return tas1.order - tas2.order;