Kita semua tahu bahwa bahasa Java sepenuhnya berorientasi objek. Di Java, semua objek diwarisi dari kelas objek.
Metode yang sama membandingkan alamat yang ditunjukkan oleh referensi dua objek. HashCode adalah metode lokal, yang mengembalikan nilai alamat objek. Ada dua metode di kelas ojbect sama dengan kode dan kode hash. Kedua metode ini digunakan untuk membandingkan apakah kedua objek tersebut sama.
Mengapa kita harus mengganti metode kode hash saat menulis ulang metode Equals?
Ini dapat dipahami sebagai berikut: Setelah menulis ulang metode yang sama, logika bisnis untuk menilai kesetaraan objek akan berubah. Perancang kelas tidak ingin membandingkan kesetaraan dua objek dengan membandingkan alamat memori. Tidak ada artinya untuk terus membandingkan sesuai dengan alamat. Jadi, itu hanya berubah bersama.
Alasan lain berasal dari koleksi. Mari kita bicarakan perlahan di bawah ~
Misalnya:
Di sekolah, melalui ID siswa untuk menentukan apakah orang ini menjadi milik.
Skenario dalam kode di bawah ini adalah entri catatan siswa, nomor siswa 123 ditugaskan untuk siswa Tom, siswa nomor 456 ditugaskan untuk siswa Jerry, dan nomor siswa 123 ditugaskan untuk Lily karena kesalahan. Namun, jumlah siswa yang sama tidak boleh terjadi selama proses mendaftarkan status siswa.
Bergantung pada persyaratan situasional, objek duplikat tidak dapat ditambahkan, dan dapat diimplementasikan melalui hashset.
Tes Kelas Publik {public static void main (string [] args) {student stu = siswa baru (123, "tom"); hashset <spudaya> set = hashset baru <> (); set.add (stu); set.add (siswa baru (456, "jerry")); set.add (siswa baru (123, "lily (456," jerry "); while (iterator.hasnext ()) {student student = iterator.next (); System.out.println (student.getstunum () + "---" + student.getName ());}}}; class student {private int stunum; nama string pribadi; siswa publik (int stunum, name string) {this.stunum = stunum; this.name = name;} public int getstunum () {stunum = stunum; this.name = name;} public int public getstunum () {stunum = stunum; this.name = name;} public int public getstunum () {stunum = stunum; this nama;}@overridepublic boolean sama dengan (objek obj) {if (this == obj) mengembalikan true; if (instance dari siswa) {if (this.getstunum () == ((siswa) obj) .getstunum ()) return true;} return false;}} Outputnya adalah:
123 --- Lily
456 --- Jerry
123 --- Tom
Berdasarkan output, kami menemukan bahwa menetapkan nomor siswa 123 untuk Lily lagi berhasil. Apa yang salah?
Mari kita lihat metode Hashset:
public boolean add (e e) {return map.put (e, present) == null;} Faktanya, hashset diimplementasikan melalui hashmap, jadi kami melacak metode Hashmap:
public v put (K key, nilai v) {if (tabel == kosong_table) {inflatetable (threshold);} if (key == null) return putfornulkKey (nilai); int hash = hash (key); int i = indexfor (hash, tabel. hash && ((k = e.key) == key || key.equals (k))) {v oldValue = e.Value; e.Value = value; e.recordaccess (ini); return oldValue;}} modcount ++; addentry (hash, kunci, nilai, i); return null;}1. Menurut kunci, yaitu, objek yang akan ditambahkan oleh hashset, mendapatkan kode hash, dan kode hash digunakan untuk melakukan operasi bit spesifik untuk mendapatkan kode hash;
2. Gunakan penentuan posisi kode hash untuk menemukan subskrip array untuk mendapatkan tautan tautan dari daftar yang ditautkan;
3. Lintasi daftar yang ditautkan untuk mengetahui apakah ada kunci yang sama. Dasar untuk penilaian adalah e.hash == hash && ((k = e.key) == key || key.equals (k)). Saat menambahkan Lily, karena metode yang sama ditulis ulang, kondisi kedua harus benar saat melintasi Tom; Tetapi karena metode kode hash masih menggunakan kelas induk, kode hash Tom dan Lily berbeda, yaitu, kode hash berbeda, dan kondisi pertama salah. Di sini kita mendapatkan bahwa kedua objek itu berbeda sehingga Hashset menambahkan Lily dengan sukses.
Alasannya adalah bahwa metode kode hash tidak menulis ulang. Ini modifikasi:
Tes Kelas Publik {public static void main (string [] args) {student stu = siswa baru (123, "tom"); hashset <spudaya> set = hashset baru <> (); set.add (stu); set.add (siswa baru (456, "jerry")); set.add (siswa baru (123, "lily (456," jerry "); while (iterator.hasnext ()) {student student = iterator.next (); System.out.println (student.getstunum () + "---" + student.getName ());}}}; class student {private int stunum; nama string pribadi; siswa publik (int stunum, name string) {this.stunum = stunum; this.name = name;} public int getstunum () {stunum = stunum; this.name = name;} public int public getstunum () {stunum = stunum; this.name = name;} public int public getstunum () {stunum = stunum; this name;}@Overridepublic boolean equals(Object obj) {if(this==obj)return true;if(obj instanceof Student){if(this.getStuNum()==((Student)obj).getStuNum())return true;}return false;}@Overridepublic int hashCode() {return getStuNum();}} Keluaran:
456 --- Jerry
123 --- Tom
Tulis ulang metode kode hash dan kembalikan nomor siswa. Oke, sudah selesai.
Beberapa orang mungkin bertanya -tanya, e.hash == hash && ((k = e.key) == key || key.equals (k)) agak rumit? Saya pikir itu cukup untuk hanya menggunakan metode Equals. Mengapa Anda perlu menilai kode hash dalam sekali jalan?
Karena ketika melintasi dan menilai dalam struktur daftar hashmap yang ditautkan, logika bisnis metode yang ditulis ulang lebih rumit untuk membandingkan apakah objek tersebut sama dalam situasi tertentu, dan logika bisnis looping down akan mempengaruhi efisiensi pencarian. Jadi di sini kita menempatkan penilaian kode hash terlebih dahulu. Selama kode hash tidak sama, Anda akan selesai bermain, dan tidak perlu menyebut setara dengan kompleks lagi. Meningkatkan efisiensi hashmap sebagian besar.
Oleh karena itu, metode kode hash adalah untuk memungkinkan kita menggunakan kelas koleksi seperti hashmap secara normal, karena hashmap menentukan apakah objek sama, baik kode hash dan sama dengan perbandingan. Implementasi ini adalah untuk meningkatkan efisiensi hashmap.