Semasa pelaksanaan aplikasi, selagi maklumat yang digunakan dalam operasi perbandingan kaedah equals objek tidak diubah suai, maka objek yang sama dipanggil berbilang kali, dan kaedah hashCode mesti secara konsisten mengembalikan integer yang sama. Semasa berbilang pelaksanaan aplikasi yang sama, integer yang dikembalikan oleh setiap pelaksanaan mungkin tidak konsisten.
Jika dua objek adalah sama mengikut perbandingan kaedah equals(Object), maka memanggil kaedah hashCode mana-mana objek mesti menghasilkan hasil integer yang sama . Sebaliknya, jika kaedah hashCode dua objek mengembalikan hasil integer yang sama, ini tidak bermakna kedua-dua objek adalah sama, kerana kaedah equals boleh terlebih beban.
Jika dua objek tidak sama mengikut perbandingan kaedah equals(Object), maka memanggil kaedah hashCode mana-mana objek tidak semestinya menghasilkan keputusan integer yang berbeza. Walau bagaimanapun, jika anda boleh membuat objek yang berbeza menghasilkan hasil integer yang berbeza, adalah mungkin untuk meningkatkan prestasi jadual cincang.
hashCodePengiraan kod cincang (daripada: Java Berkesan)
menyimpan nilai pemalar bukan sifar, seperti 17, dalam pembolehubah jenis result bernama int.
Untuk setiap medan kunci f dalam objek ( merujuk kepada setiap medan equals yang terlibat dalam kaedah ), lengkapkan langkah berikut:
Mengira kod cincang c jenis int untuk medan ini:
Menilai (boolean) jika medan adalah jenis f?1:0.
Jika medan daripada jenis byte, char, short atau int, maka (int)f dikira.
Menilai long jika medan adalah jenis (int)(f^(f>>>32)).
Menilai float jika medan adalah jenis Float.floatToIntBits(f).
Jika medan daripada jenis double, hitung Double.doubleToLongBits(f), dan kemudian ikut langkah 2.1.3 untuk mengira nilai cincang bagi nilai taip long yang terhasil.
Jika medan ialah rujukan objek dan kaedah equals kelas membandingkan medan dengan memanggil equals secara rekursif, maka ia juga memanggil hashCode secara rekursif untuk medan itu. Jika perbandingan yang lebih kompleks diperlukan, hitung bentuk biasa (canonical representation) untuk medan dan kemudian panggil hashCode terhadap bentuk biasa ini. Jika nilai medan ini ialah null, maka 0 dikembalikan (pemalar lain juga boleh diterima).
Jika medan ialah tatasusunan, setiap elemen hendaklah dianggap sebagai medan berasingan. Iaitu, gunakan peraturan di atas secara rekursif, kira kod cincang untuk setiap elemen penting, dan kemudian gabungkan nilai cincang ini mengikut langkah 2.2. Jika setiap elemen dalam medan tatasusunan adalah penting, anda boleh memanfaatkan salah satu kaedah yang ditambahkan dalam keluaran 1.5Arrays.hashCode.
Mengikut formula berikut, gabungkan kod cincang c yang dikira dalam langkah 2.1 ke dalam result: result = 31 * result + c; //Di sini 31 ialah nombor perdana ganjil, dan terdapat sangat A ciri yang bagus, menggunakan anjakan dan penolakan dan bukannya pendaraban, boleh membawa kepada prestasi yang lebih baik: `31*i == (i<<5) - i JVM Moden boleh melengkapkan pengoptimuman ini secara automatik.
Kembaliresult
Sahkan dan uji bahawa pelaksanaan hashCode mematuhi konvensyen biasa.
Contoh pelaksanaan
@Override
public int hashCode() {
int result = 17;
result = 31 * result + (origin == null ? 0 : origin.hashCode());
result = 31 * result + (hsNumber == null ? 0 : hsNumber.hashCode());
result = 31 * result + (imageUrl == null ? 0 : imageUrl.hashCode());
result = 31 * result + (classificationName == null ? 0 : classificationName.hashCode());
return result;
}
Int Java ditetapkan kepada 32 bit. Selain itu, latitud dan longtitud anda adalah dua kali ganda... Saya rasa ia akan menjadi 64-bit.
Kod cincang dan setara telah bersetuju dengan semantik Anda boleh melihat Objek
Saya rasa persamaan yang anda tulis boleh digunakan.
Nota: Kontrak dalam kelas Objek sebenarnya adalah kekangan yang sangat lemah. Kita boleh menulis hashcode() dan equals() seperti ini tanpa melanggar kontrak;
public int hashcode() {
return 0;
}
public boolean equals(Object o) {
return (o != null) && (o.getClass() == getClass());
}
Jadi persoalan sebenar ialah bagaimana anda mentakrifkan kesaksamaan. Kod adalah kedua. Jika kesaksamaan ditakrifkan sebagai "longitud dan latitud masing-masing adalah sama", maka kod yang anda berikan ialah penyelesaian yang boleh digunakan (tetapi bukan satu-satunya penyelesaian yang tersedia).
Konvensyen am untuk melaksanakan
hashCode
kaedahhashCode
Pengiraan kod cincang (daripada: Java Berkesan)Contoh pelaksanaan
Int Java ditetapkan kepada 32 bit. Selain itu, latitud dan longtitud anda adalah dua kali ganda... Saya rasa ia akan menjadi 64-bit.
Kod cincang dan setara telah bersetuju dengan semantik Anda boleh melihat Objek
Saya rasa persamaan yang anda tulis boleh digunakan.
Nota: Kontrak dalam kelas Objek sebenarnya adalah kekangan yang sangat lemah. Kita boleh menulis hashcode() dan equals() seperti ini tanpa melanggar kontrak;
Jadi persoalan sebenar ialah bagaimana anda mentakrifkan kesaksamaan. Kod adalah kedua.
Jika kesaksamaan ditakrifkan sebagai "longitud dan latitud masing-masing adalah sama", maka kod yang anda berikan ialah penyelesaian yang boleh digunakan (tetapi bukan satu-satunya penyelesaian yang tersedia).