it-swarm-id.com

Metode perbandingan melanggar kontrak umum! Hanya Java 7

Saya tahu ini telah menjadi masalah untuk sementara waktu sekarang, dan memeriksa semua jawaban yang sebelumnya bisa saya dapatkan, tapi tetap saja ini tidak berhasil.

Objek 'kru' mewakili anggota kru dengan pangkat dan barang-barang lainnya. Perbandingan harus dilakukan dengan membandingkan 'assign_rank', nilai int, dan jika nilai ini sama dalam kedua contoh, maka 'is_trainer', boolean, harus membuat perbedaan.

Metode ini bekerja dengan baik selama itu berjalan dengan Java <7. Tapi sejak Java 7 saya terus mendapatkan yang ini:

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)

Inilah sumbernya, di mana beberapa bagian yang berpotensi berbahaya telah dikomentari, tetapi tetap tidak berfungsi:

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

}

Menerapkan equals () hanya mencoba memecahkan masalah ini. Pengecualian yang diberikan datang dengan atau tanpa sama dengan (). Saya tidak dapat melihat bagaimana metode compareTo melanggar kontraknya. Setiap bantuan sangat dihargai .... suatu hari kode ini harus bekerja dengan Java 7 dan saya tidak tahu caranya ... Terima kasih

32
user1007068

lihat ini:

Dari http://www.Oracle.com/technetwork/Java/javase/compatibility-417013.html#source

Area: API: Utilitas Sinopsis: Perilaku sortir yang diperbarui untuk Array dan Koleksi dapat melempar IllegalArgumentException

Deskripsi: Algoritma pengurutan yang digunakan oleh Java.util.Arrays.sort dan (secara tidak langsung) oleh Java.util.Collections.sort telah diganti. Yang baru implementasi semacam dapat melempar IllegalArgumentException jika mendeteksi Sebanding yang melanggar kontrak Sebanding. Sebelumnya implementasi diam-diam mengabaikan situasi seperti itu. Jika sebelumnya perilaku yang diinginkan, Anda dapat menggunakan sistem baru properti Java.util.Arrays.useLegacyMergeSort, untuk mengembalikan sebelumnya perilaku mergesort.

Sifat Ketidakcocokan: perilaku

RFE: 6804124

Untuk info lebih rinci, lihat database bug referensi di sini .

44
naresh

mungkin Anda hanya memiliki nilai NaN yang Anda bandingkan melalui Collections.sort(...), ini telah menjadi masalah bagi saya dan saya mendapatkan pengecualian itu bahkan memiliki implementasi metode compare(obj1, obj2) yang benar! Periksa itu!

9
user2224477

Saya dapat mengatasi kesalahan ini karena itu adalah bug di jdk7.

di sini saya menemukan solusinya:

"Metode perbandingan melanggar kontrak umum!" - TimSort dan GridLayout

Pada dasarnya saya hanya perlu menambahkan 

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

ke jboss saya

5
cabaji99

Sayangnya, tidak ada solusi yang berfungsi untuk Android. TimSort digunakan jauh di dalam Android ViewGroup yang berkaitan dengan addChildrenForAccessibility yang muncul di Java 7 & 8. Tidak ada kode pengguna yang terlibat dalam perbandingan apa pun.

Dari laporan lain, ini terkait dengan memiliki RelativeLayout dengan item yang tumpang tindih seperti yang biasa dilakukan. Misalnya, TextView yang muncul di atas Gambar, atau dua item di lokasi yang sama, di mana Anda hanya mengatur satu yang terlihat pada satu waktu . https://code.google.com/p/Android/issues/ detail? id = 55933

Saya tidak menemukan jalan keluar bug. Anda tidak dapat mengatur opsi -Djava di Android Studio atau Eclipse (setidaknya yang bisa saya temukan). Memaksa penggunaan Java 1.6 seharusnya berhasil, tetapi tidak. Sepertinya tablet dan ponsel Fire Amazon yang lebih baru jauh lebih sensitif terhadap bug ini daripada perangkat lain.

Ada rumor bahwa Java 9 akan memperbaiki seperti opsi run-time yang berfungsi, tetapi dengan bug yang telah ada selama bertahun-tahun, saya ragu itu akan diperbaiki - terutama mengingat permusuhan antara Oracle dan Google. Ya, mungkin bug itu benar-benar dalam di kode Android dan harus diperbaiki di sana. Dengan lebih dari satu miliar perangkat di luar sana, itu bukan solusi yang layak untuk semua perangkat yang ada.

0
Frank