Pertanyaan Java Integer compareTo () - mengapa menggunakan perbandingan vs pengurangan?


Saya telah menemukan itu java.lang.Integer implementasi dari compareTo metode terlihat sebagai berikut:

public int compareTo(Integer anotherInteger) {
    int thisVal = this.value;
    int anotherVal = anotherInteger.value;
    return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}

Pertanyaannya adalah mengapa menggunakan perbandingan daripada pengurangan:

return thisVal - anotherVal;

76
2018-04-28 10:59


asal


Jawaban:


Ini karena limpahan bilangan bulat. Kapan thisVal sangat besar dan anotherVal negatif kemudian mengurangi yang terakhir dari hasil sebelumnya, hasil yang lebih besar dari thisVal yang mungkin meluap ke kisaran negatif.


85
2018-04-28 11:02



The pengurangan "trik" untuk membandingkan dua nilai numerik rusak !!!

        int a = -2000000000;
        int b =  2000000000;
        System.out.println(a - b);
        // prints "294967296"

Sini, a < b, belum a - b positif.

JANGAN gunakan idiom ini. Itu tidak berhasil.

Bahkan, bahkan jika itu berhasil, itu akan TIDAK memberikan peningkatan yang signifikan dalam kinerja, dan mungkin pada kenyataannya biaya pembacaan.

Lihat juga

  • Java Puzzlers Teka-Teki 65: Saga Aneh yang Mencurigakan

    Teka-teki ini memiliki beberapa pelajaran. Yang paling spesifik adalah: Jangan gunakan komparator berbasis pengurangan kecuali Anda yakin bahwa perbedaan antara nilai tidak akan pernah lebih besar daripada  Integer.MAX_VALUE. Lebih umum, waspadalah terhadap int meluap. Pelajaran lain adalah Anda harus menghindari kode "pintar". Berusahalah untuk menulis kode yang jelas dan benar, dan jangan mengoptimalkannya kecuali terbukti perlu.


60
2018-04-28 11:09



Cukup berbicara, itu int Jenisnya tidak cukup besar untuk menyimpan perbedaan antara dua sewenang-wenang int nilai-nilai. Misalnya, selisih antara 1,5 miliar dan -1,5 miliar adalah 3,0 miliar, tetapi int tidak dapat menyimpan nilai lebih dari 2,1 miliar.


9
2018-04-28 12:03



Mungkin itu untuk menghindari overflow / underflow.


3
2018-04-28 11:02



Selain hal yang melimpah, Anda harus mencatat bahwa versi dengan substraksi tidak memberikan hasil yang sama.

  • Versi compareTo pertama mengembalikan salah satu dari tiga nilai yang mungkin: -1, 0, atau 1.
  • Jika Anda mengganti baris terakhir dengan substraksi, hasilnya bisa berupa nilai bilangan bulat apa pun.

Jika Anda tahu tidak akan ada overflow, Anda bisa menggunakan sesuatu seperti ini:

public int compareTo(Integer anotherInteger) {
    return sign(this.value - anotherInteger.valuel);
}

1
2018-04-28 13:23