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

use*_*068 34 compareto java-7

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

对象'船员'代表有船员和其他物品的船员.比较应该通过比较'assigned_rank',一个int值,如果这两个实例中的值相等,那么'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)
Run Code Online (Sandbox Code Playgroud)

这是源代码,其中一些有潜在危险的部分已经被评论过,但它仍然不起作用:

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;
}
Run Code Online (Sandbox Code Playgroud)

}

实现equals()只是尝试解决这个问题.给定的异常带或不带equals().我看不出compareTo方法如何违反其合同.非常感谢任何帮助....有一天这个代码必须与java 7一起工作,我不知道如何...谢谢

nar*_*esh 45

看到这个:

来自http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#source

区域:API:实用程序概要:数组和集合的更新排序行为可能会抛出IllegalArgumentException

描述:java.util.Arrays.sort和(间接)java.util.Collections.sort使用的排序算法已被替换.如果新的排序实现检测到违反Comparable合同的Comparable,则可能抛出IllegalArgumentException.以前的实现默默地忽略了这种情况.如果需要以前的行为,则可以使用新的系统属性java.util.Arrays.useLegacyMergeSort来恢复以前的mergesort行为.

不相容的性质:行为

RFE:6804124

有关更多详细信息,请参阅此处的错误数据库参考.

  • 是的,但compareTo实现如何违反合同? (5认同)

小智 9

也许你只有NaN你比较的价值Collections.sort(...),这对我来说是一个问题,即使正确实施compare(obj1, obj2)方法我也得到了这个例外!检查一下!

  • 那是我的问题.谢谢!:) (2认同)

cab*_*i99 5

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

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

"比较方法违反了其总合同!" - TimSort和GridLayout

基本上我只需要添加

JAVA_OPTS="$JAVA_OPTS -Djava.util.Arrays.useLegacyMergeSort=true"
Run Code Online (Sandbox Code Playgroud)

到我的jboss

  • 这不是jdk7中的错误,而是代码中的错误.;-)它违反了比较方法的必要条件. (8认同)