Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的比较方法抛出异常——比较方法违反了它的一般约定!_Java_Android_Comparator_Contract - Fatal编程技术网

Java 为什么我的比较方法抛出异常——比较方法违反了它的一般约定!

Java 为什么我的比较方法抛出异常——比较方法违反了它的一般约定!,java,android,comparator,contract,Java,Android,Comparator,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

为什么这个代码

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;
    }
}
公共类发起的Comparator实现Comparator{
公共布尔等于(SRE arg0,SRE arg1){
返回arg0.getSponsorted()==arg1.getSponsorted();
}
公共整数比较(SRE对象1、SRE对象2){
Log.d(“SponsoredComparator”,“object1.getName()=”+object1.getName());
Log.d(“受赞助的比较器”,“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));
返回object1.getSponsorted()&&object2.getSponsorted()?0:object1.getSponsorted()?-1:1;
}
}
抛出此异常:
ERROR/AndroidRuntime(244):java.lang.IllegalArgumentException:比较方法违反其一般约定
ERROR/AndroidRuntime(4446):位于java.util.TimSort.mergeLo(TimSort.java:743)

方法sre.getSponsored()返回一个布尔值


谢谢。

我怀疑这两个值都没有赞助时会出现问题。不管你怎么称呼它,它都会返回1,即

x1.compare(x2) == 1

x2.compare(x1) == 1
那是无效的

我建议你改变这一点:

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());
}

这将使代码更清晰,我认为。

equals()和compareTo()之间的约定是,当equals()返回true时,compareTo()应返回0,当equals()为false时,compareTo应返回-1或+1


顺便说一句:我假设您的compare()方法不经常被调用,因为调试消息将占用大量的CPU和内存。

我假设您使用的是JDK 7。检查以下URL:

领域:API:实用程序

简介:更新的
数组
集合
的排序行为可能引发
IllegalArgumentException

Description:java.util.Arrays.sort使用的排序算法 (间接地)被
java.util.Collections.sort
替换。新的 如果排序实现检测到 违反
可比
合同的
可比
。前 执行默默地忽略了这种情况。如果以前的 如果需要行为,可以使用新系统 属性,
java.util.Arrays.useLegacyMergeSort
,以还原以前的 合并排序行为

不相容性的性质:行为

传真:6804124


有关更详细的信息,请参阅bug数据库。

可能您只是拥有通过集合进行比较的NaN值。排序。。。这对我来说是个问题,即使正确实现了compare(obj1,obj2)方法,我也遇到了这个异常!检查一下

我特别同意jon的所有回答,但还有一件事我想告诉你,我们应该始终检查compare方法中的空安全性,这样我们的方法就永远不会被破坏,并且总是空检查是编程中的一个好习惯。有关更多信息,请看

我今天在一个web应用程序中遇到了同样的问题。在同一个数组上工作的四个调用试图同时对其进行排序,这实际上会把彼此弄乱。

我的解决方案:当我要对数字进行排序,并且数组元素为空时,我将0放入,然后错误消失。需要注意的是,二维数组中每一行的大小是相同的

这些调试消息只是为了帮助修复此错误。正如文档所述,“强烈建议,但不严格要求(x.compareTo(y)==0)==(x.equals(y))”。而这个问题的例外并不是从用equals方法违约中衍生出来的。我在这个旧答案上写这篇评论是因为它让我得出了错误的结论,即在这种例外情况下违约可能与平等有关method@Peter这是我发现的第一个信息,有人说得很清楚,合同到底是什么。谢谢大家,但是鉴于equals必须返回一个与compareTo相对应的值,我认为对于所有实现compareTo的用户来说,最好的解决方案是重写equals,并在这个方法中简单地调用compareTo,如果结果为0,则返回true,如果结果不是0,则返回false。唯一需要注意的是,在compareTo中不能调用equals。@zreptil使用compareTo有一些问题;a) 有时两个值可以相等,但compareTo不是0,例如-0.0和0.0以及BigDecimal值。另一个问题是,两个值可能没有任何合理的高或低概念,你不能检查是否相等。@Peter Lawrey我认为compareTo可以毫无问题地使用。它为我工作了好几年,直到java团队决定违反compareTo和equals之间的契约必须抛出一个异常,这并没有真正澄清到底出了什么问题。我很少使用compareTo,但它是一种方便的方法,可以比较一个类的两个实例,以确定哪一个必须在另一个实例之前排序。在了解了合同的细节后,针对该异常的错误修复非常简单,而且工作起来非常简单。这与您遇到的问题没有直接关系,但是您是否需要担心空值?您几乎是对的。OP使用Android(而不是JDK 7),但您的引用仍然正确,因为JDK 7和Android都使用
TimSort
算法,如果与违反
Compariable
合同的
Compariable
一起使用,则抛出
IllegalArgumentException
public int compare(SRE object1, SRE object2) {
    return BooleanHelper.compare(object1.getSponsored(), object2.getSponsored());
}