Java 7 比较法违反其总合同!仅限Java 7

Java 7 比较法违反其总合同!仅限Java 7,java-7,compareto,Java 7,Compareto,我知道这是一个问题已经有一段时间了,我检查了所有以前我能得到的答案,但这个仍然不起作用 对象“crew”表示拥有军衔和其他物品的乘员。比较应该通过比较一个int值“assigned_rank”来进行,如果这个值在两种情况下都相等,那么布尔值“is_trainer”应该会产生差异 只要在javahisRank){ 返回1; } 如果(myRankhisRank){ 返回false; } 如果(myRank

我知道这是一个问题已经有一段时间了,我检查了所有以前我能得到的答案,但这个仍然不起作用

对象“crew”表示拥有军衔和其他物品的乘员。比较应该通过比较一个int值“assigned_rank”来进行,如果这个值在两种情况下都相等,那么布尔值“is_trainer”应该会产生差异

只要在java<7的环境下运行,这种方法就非常有效。但自从Java 7以来,我一直得到这个:

java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.ComparableTimSort.mergeLo(ComparableTimSort.java:714)
at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:451)
at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:376)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:182)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
at dormas_flightlog.Query.getCrew(Query.java:714)
以下是来源,其中一些潜在的危险部件已被注释掉,但仍然不起作用:

public class crew implements Serializable, Comparable<crew> {

private static final long serialVersionUID = 36L;
private int flightID = 0;
private int assigned_rank = 25;
private boolean is_trainer = false;
...


@Override
public int compareTo(crew him) {

    int myRank = this.getAssigned_rank();
    int hisRank = him.assigned_rank;

    if (this == him) {
        return 0;
    }
    if (myRank > hisRank) {
        return 1;
    }
    if (myRank < hisRank) {
        return -1;
    }
    if (myRank == hisRank) {
//            if (is_trainer && !o.is_trainer) {
//                i = 1;
//            }
//            if (!is_trainer && o.is_trainer) {
//                i = -1;
//            }
//            if (is_trainer && o.is_trainer) {
//                i = 0;
//            }
//            if (!is_trainer && !o.is_trainer) {
//                i = 0;
//            }
        return 0;
    }

    return 0;
}

@Override
public int hashCode() {
    int hash = 7;
    hash = 31 * hash + this.assigned_rank;
    hash = 31 * hash + (this.is_trainer ? 1 : 0);
    return hash;
}

@Override
public boolean equals(Object o) {

    if (this == o) {
        return true;
    }


    int myRank = this.getAssigned_rank();
    int hisRank = 0;

    if (o instanceof crew) {
        crew him = (crew) o;
        hisRank = him.assigned_rank;
    } else {
        return false;
    }

    if (myRank > hisRank) {
        return false;
    }
    if (myRank < hisRank) {
        return false;
    }
    if (myRank == hisRank) {
//            if (is_trainer && !o.is_trainer) {
//                i = 1;
//            }
//            if (!is_trainer && o.is_trainer) {
//                i = -1;
//            }
//            if (is_trainer && o.is_trainer) {
//                i = 0;
//            }
//            if (!is_trainer && !o.is_trainer) {
//                i = 0;
//            }
        return true;
    }

    return false;
}
public class crew实现了可序列化、可比较的{
私有静态最终长serialVersionUID=36L;
private int flightID=0;
分配的私有int_秩=25;
私有布尔值为_trainer=false;
...
@凌驾
公共内部比较(组员him){
int myRank=this.getAssigned_rank();
int hisRank=him.assigned_秩;
如果(这个==他){
返回0;
}
如果(myRank>hisRank){
返回1;
}
如果(myRankhisRank){
返回false;
}
如果(myRank
}

实现equals()只是为了解决这个问题。给定的异常包含或不包含equals()。我看不出compareTo方法是如何违反其约定的。非常感谢您的帮助…有一天,这段代码必须与java 7一起工作,我不知道如何。。。 谢谢

见此:

领域:API:实用程序概要:更新了数组和 集合可能引发IllegalArgumentException

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

不相容性的性质:行为

传真:6804124


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

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

我能够解决这个错误,因为它是jdk7中的一个bug

在这里,我找到了解决方案:

基本上我只需要添加

JAVA_OPTS="$JAVA_OPTS -Djava.util.Arrays.useLegacyMergeSort=true"

对我的jboss来说,不幸的是,没有一个解决方案适用于Android。TimSort在Android的视图组中被深入使用,该视图组与addChildrenForAccessibility相关,显示在Java 7和8中。任何比较都不涉及用户代码

从其他报告中可以看出,这与通常所做的重叠项的相对性有关。例如,显示在图像上的文本视图,或同一位置的两个项目,在其中一次仅设置一个可见项。

我还没有找到任何方法来解决这个问题。你不能在Android Studio或Eclipse中设置-Djava选项(至少我能找到)。强制使用Java1.6应该可以,但是不行。亚马逊新推出的Fire平板电脑和手机似乎比其他设备对这个漏洞更加敏感


有传闻说Java 9将有一个修复程序,比如运行时选项,可以正常工作,但由于存在多年的bug,我怀疑它是否会被修复——特别是考虑到Oracle和Google之间的敌意。是的,也许这个bug在Android代码中很深,应该在那里修复。有超过10亿台设备,这不是所有现有设备的可行解决方案。

你能显示你在哪里进行排序的代码吗?assigned_rank和getAssigned_rank()之间的区别是什么?类似的问题问到你有没有找到真正的解决方案(除了像naresh建议的那样抑制警告)?在我的案例中,类似的代码也有同样的问题。我开始认为这是库代码中的一个bug。你的代码看起来不错。您是否有一些发生这种情况的示例对象(或者最好是一个完整的最小示例)?这就是我的问题。谢谢!:)是的,但是compareTo实现是如何违反契约的?@hstoerr请参阅,如果您给出一个OP代码违反所需IReflex的示例,这将非常有帮助