Rumah > Soal Jawab > teks badan
PHP中文网2017-04-18 10:47:27
Konvensyen am untuk melaksanakan hashCode
kaedah
Semasa pelaksanaan aplikasi, selagi maklumat yang digunakan dalam operasi perbandingan kaedah
equals
objek tidak diubah suai, maka objek yang sama dipanggil berbilang kali, dan kaedahhashCode
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 kaedahhashCode
mana-mana objek mesti menghasilkan hasil integer yang sama . Sebaliknya, jika kaedahhashCode
dua objek mengembalikan hasil integer yang sama, ini tidak bermakna kedua-dua objek adalah sama, kerana kaedahequals
boleh terlebih beban.Jika dua objek tidak sama mengikut perbandingan kaedah
equals(Object)
, maka memanggil kaedahhashCode
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.
hashCode
Pengiraan kod cincang (daripada: Java Berkesan)
menyimpan nilai pemalar bukan sifar, seperti
17
, dalam pembolehubah jenisresult
bernamaint
.Untuk setiap medan kunci
f
dalam objek ( merujuk kepada setiap medanequals
yang terlibat dalam kaedah ), lengkapkan langkah berikut:
Mengira kod cincang c jenis
int
untuk medan ini:
Menilai (
boolean
) jika medan adalah jenisf?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 jenisFloat.floatToIntBits(f)
.Jika medan daripada jenis
double
, hitungDouble.doubleToLongBits(f)
, dan kemudian ikut langkah 2.1.3 untuk mengira nilai cincang bagi nilai taiplong
yang terhasil.Jika medan ialah rujukan objek dan kaedah
equals
kelas membandingkan medan dengan memanggilequals
secara rekursif, maka ia juga memanggilhashCode
secara rekursif untuk medan itu. Jika perbandingan yang lebih kompleks diperlukan, hitung bentuk biasa(canonical representation)
untuk medan dan kemudian panggilhashCode
terhadap bentuk biasa ini. Jika nilai medan ini ialahnull
, maka0
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.5
Arrays.hashCode
.Mengikut formula berikut, gabungkan kod cincang
c
yang dikira dalam langkah 2.1 ke dalamresult
:result = 31 * result + c
; //Di sini31
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.Kembali
result
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;
}
大家讲道理2017-04-18 10:47:27
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).