Ini adalah pertanyaan yang sangat klasik di Java dan sering ditanya selama wawancara. Bahkan, banyak buku atau artikel telah menyebutkan bahwa Anda harus kelebihan beban hashcode () dan equals () untuk mewujudkan pencarian kunci khusus di hashmap. Namun, tampaknya beberapa artikel berbicara tentang mengapa Anda perlu melakukan ini dan konsekuensi apa yang akan disebabkan oleh tidak melakukan ini, jadi saya akan menulis artikel ini untuk menjelaskannya.
Pertama -tama, apa yang terjadi jika kita secara langsung menggunakan kelas orang berikut sebagai kunci dan menyimpannya di hashmap?
orang kelas publik {private string id; orang publik (ID String) {this.id = id; }} import java.util.hashmap; kelas publik utama {public static void main (string [] args) {hashMap <Person, string> map = new HashMap <Person, String> (); peta.put (orang baru ("001"), "findingsea"); peta.put (orang baru ("002"), "linyin"); Map.put (orang baru ("003"), "Henrylin"); peta.put (orang baru ("003"), "findingsealy"); System.out.println (MAP.ToString ()); System.out.println (Map.get (orang baru ("001"))); System.out.println (Map.get (orang baru ("002"))); System.out.println (Map.get (orang baru ("003"))); }}Jadi apa hasil outputnya?
{Person@6e4d4d5e = henrylin, orang@275cea3 = findingsea, orang@15128ee5 = findingealey, orang@4513098 = linyin} nullnullnullKita dapat melihat bahwa ada dua masalah di sini:
1. Selama proses penambahan, kami menambahkan pasangan nilai kunci dari kunci = orang baru ("003") dua kali. Dalam harapan, seharusnya hanya ada satu pasangan nilai kunci dalam hashmap. Karena kunci (yang diharapkan) sama, tidak boleh ditambahkan berulang kali. Nilai = "Temuan Bersih" menambahkan kedua kalinya harus menggantikan nilai asli = "Henrylin". Tetapi dalam input, kami menemukan bahwa situasi yang diharapkan tidak terjadi, tetapi ada dua pasangan nilai kunci dari nilai = "temuan yang saya sukai" dan nilai = "henrylin" dalam hashmap, dan nilai-nilai utama mereka masih berbeda, yang jelas salah.
2. Saat mendapatkan nilai nilai, kami menggunakan tiga objek orang untuk mencari. Ketiga objek ini sama dengan tiga nilai utama yang baru saja kami simpan (dengan harapan), tetapi pencarian adalah tiga nilai nol, yang jelas juga salah.
Jadi, metode yang benar sebenarnya telah dijelaskan di banyak tempat. Kelas orang dimodifikasi secara langsung, sama dengan metode kode hash, dan kelas orang yang dimodifikasi adalah sebagai berikut:
orang kelas publik {private string id; orang publik (ID String) {this.id = id; } @Override public boolean sama (objek o) {if (this == o) return true; if (o == null || getClass ()! = o.getClass ()) mengembalikan false; Orang orang = (orang) o; if (id! = null ?! id.equals (person.id): person.id! = null) return false; Kembali Benar; } @Override public int hashCode () {return id! = Null? id.hashcode (): 0; }}Kemudian, ketika kami mengeksekusi ulang prosedur inspeksi di atas, hasilnya adalah sebagai berikut:
{Person@ba31 = findingsea, person@ba32 = linyin, orang@ba33 = findingsealy} findingsealinyinfindingsealySeperti yang dapat dilihat, semua highlight dan kesalahan yang ditunjukkan telah diperbaiki. Jadi, mengapa ini terjadi?
Dalam hashmap, urutan perbandingan tombol pencarian adalah:
1. Hitung kode hash objek untuk melihat apakah ada dalam tabel.
2. Periksa apakah objek di lokasi kode hash yang sesuai sama dengan objek saat ini.
Jelas, langkah pertama adalah menggunakan metode hashcode (), dan langkah kedua adalah menggunakan metode Equals (). Ketika tidak ada kelebihan beban yang dilakukan, kedua metode kelas objek ini akan dipanggil secara default dalam dua langkah ini. Dalam objek, metode perhitungan kode hash dihitung berdasarkan alamat objek. Alamat objek dari dua orang ("003") berbeda, jadi kode hash mereka juga berbeda. Secara alami, hashmap tidak akan memperlakukan mereka sebagai kunci yang sama. Pada saat yang sama, di objek Equals () default, itu juga dibandingkan berdasarkan alamat objek. Secara alami, satu orang ("003") dan orang lain ("003") tidak sama.
Setelah memahami hal ini, mudah untuk mengetahui mengapa Anda perlu kelebihan beban kedua hashcode () dan sama dengan metode.
• Kelebihan kode hashcode () adalah untuk mendapatkan kode hash yang sama untuk kunci yang sama, sehingga hashmap dapat diposisikan pada kunci yang kami tentukan.
• Overloading Equals () adalah untuk menunjukkan hashmap bahwa objek saat ini dan objek yang disimpan pada kunci adalah sama, sehingga kita benar-benar dapat memperoleh pasangan nilai kunci yang sesuai dengan kunci.
Ada detail lain. Di kelas orang, penekanan pada metode hashcode () adalah:
@Overridepublic int hashCode () {return id! = Null? id.hashCode (): 0;}Poin yang mungkin bingung di sini adalah: mengapa kode hash dari variabel string tipe dapat digunakan sebagai nilai kode hash dari kelas orang? Apakah kode hash orang baru (string baru ("003")) dan orang baru (string baru ("003")) sama?
Mari kita lihat output dari kode berikut:
System.out.println ("Temuansea" .hashCode ()); System.out.println ("Temuansea" .hashCode ()); System.out.println (string baru ("Temuan Tingsea"). HashCode ()); System.out.println (baru String ("Findingsea"). HashCode ()); 728795174728795174728795174728795174Anda dapat melihat bahwa output dari empat pernyataan semuanya sama. Sangat intuitif dan masuk akal untuk menebak bahwa tipe string juga kelebihan beban hashcode () untuk mengembalikan nilai kode hash sesuai dengan konten string, sehingga string dengan konten yang sama memiliki kode hash yang sama.
Pada saat yang sama, ini juga menggambarkan sebuah pertanyaan: mengapa kita perlu menggunakan Equals () untuk perbandingan ketika kita tahu bahwa hashcode () sama? Ini karena menghindari situasi dalam contoh di atas, karena menurut implementasi kelebihan metode hashcode () dari kelas orang, kelas orang akan secara langsung menggunakan nilai kode hash dari ID Anggota Jenis String sebagai nilai kode hashnya. Namun, jelas bahwa seseorang ("003") dan string ("003") tidak sama, jadi ketika hashcode () sama, sama () juga diperlukan untuk membandingkan.
Contoh -contoh berikut dapat digunakan sebagai bukti dari deskripsi di atas:
System.out.println (orang baru ("003"). HashCode ()); // 47667system.out.println (string baru ("003"). HashCode ()); // 47667system.out.println (orang baru ("003"). Sama (string baru ("003"))); // PALSUArtikel di atas Java menggunakan kelas khusus sebagai contoh nilai kunci dari hashmap. Ini semua konten yang saya bagikan dengan Anda. Saya harap ini dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.