37

私はこれがしばらくの間問題になっていることを知っており、私が得ることができた以前のすべての答えをチェックしましたが、それでもこれは機能しません。

オブジェクト「乗組員」は、ランクやその他のアイテムを持つ乗組員を表します。比較は、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;
}

}

equals()の実装は、この問題を解決するための試みにすぎませんでした。指定された例外には、equals()がある場合とない場合があります。compareTo-methodがどのようにコントラクトに違反しているかがわかりません。どんな助けでも大歓迎です....ある日、このコードはjava 7で動作する必要があり、方法がわかりません...ありがとう

4

4 に答える 4

48

これを参照してください:

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を使用して、以前のマージソート動作を復元できます。

非互換性の性質:行動

RFE:6804124

詳細については、こちらのバグデータベースリファレンスを参照してください。

于 2011-12-07T15:02:37.890 に答える
10

たぶん、NaNあなたは比較する値を持っているだけかもしれませんがCollections.sort(...)、これは私にとって問題であり、compare(obj1, obj2)メソッドを正しく実装しても例外が発生しました! それを確認します!

于 2013-03-29T13:19:07.447 に答える