1. Mengapa HashCode ()?
Elemen -elemen dalam set set tidak teratur dan tidak dapat diulang, jadi apa dasar untuk menilai apakah dua elemen diulang? "Tentu saja, objek.Equal () digunakan untuk membandingkan apakah objeknya sama," kata kera tertentu. Namun, ada sejumlah besar objek dalam set, dan jumlah perbandingan elemen objek yang ditambahkan ke set set secara bertahap akan meningkat, sangat mengurangi efisiensi operasi program. Java menggunakan algoritma hashing (juga disebut algoritma hashing) untuk menyelesaikan masalah ini. Objek (atau data) dipetakan secara langsung ke alamat sesuai dengan algoritma tertentu, dan efisiensi akses objek sangat ditingkatkan. Dengan cara ini, ketika set himpunan yang berisi sejumlah besar elemen perlu menambahkan elemen (objek), pertama panggil kode hashcode () dari elemen ini, dan Anda dapat memposisikan lokasi penyimpanan aktual dari elemen ini sekaligus. Jika tidak ada elemen pada posisi ini, itu berarti bahwa objek disimpan dalam koleksi yang ditetapkan untuk pertama kalinya, dan objek disimpan langsung pada posisi ini; Jika ada objek pada posisi ini, hubungi Equal () untuk melihat apakah kedua objek tersebut sama. Jika hal yang sama benar, buang elemen dan tidak ada. Jika tidak sama, hash ke alamat lain.
2. Bagaimana menggunakan kode hashcode ()?
Bahasa Java memiliki lima persyaratan yang harus diikuti untuk setara () dalam desain kera.
simetri. Jika A.Equal (b) mengembalikan "Benar", maka B.Equal (a) juga harus mengembalikan "Benar".
Reflektif. A.Equal (a) harus mengembalikan "Benar".
Transitif. Jika A.Equal (b) mengembalikan "Benar" dan B.Equal (C) mengembalikan "Benar", maka C.Equal (a) harus mengembalikan "Benar".
konsistensi. Jika A.Equal (B) mengembalikan "Benar", selama konten A dan B tetap tidak berubah, tidak peduli berapa kali A.ED (B) harus mengembalikan "Benar".
Bagaimanapun, A.Equals (null) selalu mengembalikan "false"; A.Equals (objek dari berbagai jenis dan a) selalu mengembalikan "false".
Hubungan antara nilai pengembalian hashcode () dan setara ().
Jika A.Equals (b) mengembalikan "Benar", maka HashCode () dari A dan B harus sama.
Jika A.Equals (b) mengembalikan "false", maka hashcode () dari A dan B mungkin sama atau mungkin tidak setara.
Inilah contohnya. Dalam pengembangan perangkat lunak yang sebenarnya, yang terbaik adalah menulis ulang kedua metode ini.
Karyawan kelas publik {int usaha sendiri; Nama string; // Metode lain akan ada di sini @Override public boolean sama (objek obj) {if (obj == this) return true; Karyawan emp = (karyawan) obj; if (emplingeeId.equals (emp.geteMeMeMeadeeId ()) && name == emp.getName ()) return true; mengembalikan false; } @Override public int hashCode () {int hash = 1; hash = hash * 17 + karyawan; hash = hash * 31 + name.hashCode (); Hash Kembalikan; }}3. Berikut ini adalah fokus pada metode implementasi hashcode () dari kelas yang umum digunakan.
hascode () dari kelas string
public int hashCode () {int h = hash; if (h == 0) {int off = offset; char val [] = nilai; int len = hitung; untuk (int i = 0; i <len; i ++) {h = 31*h+val [OFF ++]; } hash = h; } return h; }Hal yang paling menarik tentang kode ini adalah metode implementasi hash. Nilai hash yang dihitung terakhir adalah:
S [0] 31N-1 + S [1] 31N-2 + ... + S [n-1]
S [i] adalah karakter i-th dari string, dan n adalah panjang string. Lalu mengapa menggunakan 31 di sini, bukan nomor lain?
31 adalah bilangan prima yang aneh. Jika pengganda adalah angka genap dan perkalian meluap, informasi akan hilang karena multiplikasi dengan 2 setara dengan operasi shift. Manfaat menggunakan bilangan prima tidak jelas, tetapi hasil hash secara konvensional digunakan untuk menghitung hasil hash. 31 memiliki fitur yang baik, yaitu menggunakan shift dan pengurangan alih-alih multiplikasi untuk mendapatkan kinerja yang lebih baik: 31*i == (i << 5) -i. VM dapat secara otomatis menyelesaikan optimasi ini. (Dari Java yang efektif)
hascode () dari kelas objek
HashCode () adalah metode asli di kelas objek. Bagaimana cara memanggil metode asli?
hashcode int asli int ();
Kelas metode asli dari kelas objek dapat ditemukan di sini. Harap baca blog lain untuk analisis mendalam
Statis JninativeMethod Metode [] = {{"hashCode", "() i", (void *) & jvm_ihashCode}, {"tunggu", "(j) v", (void *) & jvm_monitorWait}, {"notify", "() void *), void *) {void *), {" notify "," () void *), {void *), {void *), {void *), {void *), {void *), " "() V", (void *) & jvm_monitornotifyall}, {"clone", "() ljava/lang/objek;", (void *) & jvm_clone},};Kode sumber termasuk getClass () (lihat Line58), dll. HashCode () (lihat Line43) didefinisikan sebagai pointer ke JVM_IHashCode.
JVM.CPP mendefinisikan fungsi JVM_IHashCode (baris 504). Fungsi ini memanggil ObjectSynchronizer :: FasthashCode, yang ditentukan dalam synchronizer.cpp. Untuk implementasi fasthashCode di baris 576 dan get_next_hash di baris 530, Anda dapat merujuk pada implementasi fasthashCode di baris 576 dan get_next_hash di baris 530.