![](/img/trans.png)
[英]Why does this code throw exception - Comparison method violates its general contract
[英]why does my compare method throw exception — Comparison method violates its general contract!
为什么这个代码
public class SponsoredComparator implements Comparator<SRE> {
public boolean equals(SRE arg0, SRE arg1){
return arg0.getSponsored()==arg1.getSponsored();
}
public int compare(SRE object1, SRE object2) {
Log.d("SponsoredComparator","object1.getName() == "+ object1.getName());
Log.d("SponsoredComparator","object1.getSponsored() == "+ object1.getSponsored());
Log.d("SponsoredComparator","object2.getName() == "+ object2.getName());
Log.d("SponsoredComparator","object2.getSponsored() == "+ object2.getSponsored());
Log.d("SponsoredComparator","compare return == "+ (object1.getSponsored() && object2.getSponsored() ? 0 : object1.getSponsored() ? -1 : 1));
return object1.getSponsored() && object2.getSponsored() ? 0 : object1.getSponsored() ? -1 : 1;
}
}
抛出此异常: ERROR/AndroidRuntime(244): java.lang.IllegalArgumentException: Comparison method violates its general contract!
ERROR/AndroidRuntime(4446): at java.util.TimSort.mergeLo(TimSort.java:743)ERROR/AndroidRuntime(244): java.lang.IllegalArgumentException: Comparison method violates its general contract!
ERROR/AndroidRuntime(4446): at java.util.TimSort.mergeLo(TimSort.java:743)
方法sre.getSponsored()返回一个布尔值。
谢谢。
我怀疑当这两个价值都没有得到赞助时就会出现问题。 无论你怎么称呼,它都将返回1,即
x1.compare(x2) == 1
x2.compare(x1) == 1
那是无效的。
我建议你改变这个:
object1.getSponsored() && object2.getSponsored()
至
object1.getSponsored() == object2.getSponsored()
在这两个地方。 我可能会在某个地方用这个签名提取出一个方法:
public static int compare(boolean x, boolean y)
然后像这样调用它:
public int compare(SRE object1, SRE object2) {
return BooleanHelper.compare(object1.getSponsored(), object2.getSponsored());
}
这将使代码更清晰,IMO。
我假设您使用的是JDK 7.请检查以下URL:
来自http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#source
区域:API:实用工具
概要:
Arrays
和Collections
更新排序行为可能会抛出IllegalArgumentException
描述:
java.util.Arrays.sort
和(间接)java.util.Collections.sort
使用的排序算法已被替换。 如果新的排序实现检测到违反Comparable
合同的Comparable
,则可能抛出IllegalArgumentException
。 以前的实现默默地忽略了这种情况。 如果需要先前的行为,则可以使用新的系统属性java.util.Arrays.useLegacyMergeSort
来恢复先前的mergesort行为。不相容的性质:行为
RFE:6804124
equals()和compareTo()之间的契约是当equals()返回true时,compareTo()应返回0,当equals()为false时,compareTo应返回-1或+1。
顺便说一句:我认为你的compare()方法不经常被调用,因为调试消息会占用大量的CPU和内存。
我特别赞同jon的所有答案,但是我想告诉我们应该总是在比较方法中检查null安全性,这样我们的方法永远不会破坏,并且在编程中总是空检查是个好习惯。 有关详细信息,请查看此处
也许你只有你通过Collections.sort比较的NaN值......这对我来说是一个问题,即使正确实施了compare(obj1,obj2)方法,我也得到了这个例外! 检查一下!
我今天在Web应用程序中遇到了同样的问题。 在同一个阵列上进行的四次调用试图同时对它进行排序,有效地相互混淆。
我的解决方案:当我想对数字进行排序并且数组元素为空时,我输入0然后错误消失。 需要注意二维阵列中每行的大小是相同的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.