Baru-baru ini saya membaca Dokumen Pekerjaan Pengembang ini .
Dokumen ini adalah tentang mendefinisikan hashCode()
dan equals()
secara efektif dan benar, namun saya tidak dapat mengetahui mengapa kita perlu mengganti kedua metode ini.
Bagaimana saya bisa mengambil keputusan untuk menerapkan metode ini secara efisien?
Jawaban:
Joshua Bloch berkata di Java Efektif
Mari kita coba memahaminya dengan contoh apa yang akan terjadi jika kita menimpanya
equals()
tanpa mengesampingkanhashCode()
dan berusaha menggunakan aMap
.Katakanlah kita memiliki kelas seperti ini dan bahwa dua objek
MyClass
sama jika merekaimportantField
sama (denganhashCode()
danequals()
dihasilkan oleh gerhana)Timpa saja
equals
Jika hanya
equals
diganti, maka ketika Anda meneleponmyMap.put(first,someValue)
dulu akan hash ke beberapa ember dan ketika Anda menyebutnyamyMap.put(second,someOtherValue)
akan hash ke beberapa ember lainnya (karena mereka memiliki yang berbedahashCode
). Jadi, meskipun mereka sama, karena mereka tidak hash ke ember yang sama, peta tidak bisa menyadarinya dan mereka berdua tetap di peta.Meskipun tidak perlu untuk menimpa
equals()
jika kita menimpahashCode()
, mari kita lihat apa yang akan terjadi dalam kasus khusus ini di mana kita tahu bahwa dua objekMyClass
sama jika merekaimportantField
sama tetapi kita tidak menimpaequals()
.Timpa saja
hashCode
Bayangkan Anda memiliki ini
Jika Anda hanya menimpanya
hashCode
maka saat Anda memanggilnyamyMap.put(first,someValue)
butuh lebih dulu, hitunghashCode
dan simpan dalam ember yang diberikan. Kemudian ketika Anda memanggilnyamyMap.put(second,someOtherValue)
harus ganti dulu dengan yang kedua sesuai Dokumentasi Peta karena keduanya sama (sesuai dengan kebutuhan bisnis).Tetapi masalahnya adalah bahwa sama tidak didefinisikan ulang, jadi ketika peta hash
second
dan beralih melalui ember mencari jika ada objekk
sedemikian rupa sehinggasecond.equals(k)
benar tidak akan menemukan apa pun yangsecond.equals(first)
akan terjadifalse
.Semoga itu jelas
sumber
if you think you need to override one, then you need to override both of them
salah. Anda perlu menggantihashCode
jika kelas Anda menimpaequals
tetapi sebaliknya tidak benar.equals
akan melanggar kontrak yang tercantum dalam javadocObject
: "Jika dua objek sama denganequals(Object)
metode, maka memanggilhashCode
metode pada masing-masing dua objek harus menghasilkan hasil bilangan bulat yang sama." Tentu, tidak semua bagian dari semua kontrak dijalankan dalam semua kode, tapi tetap saja, secara resmi itu merupakan pelanggaran dan saya menganggapnya sebagai bug yang menunggu untuk terjadi.Koleksi seperti
HashMap
danHashSet
menggunakan nilai kode hash suatu objek untuk menentukan bagaimana ia harus disimpan di dalam koleksi, dan kode hash digunakan lagi untuk menemukan objek dalam koleksi.Pengambilan hashing adalah proses dua langkah:
hashCode()
)equals()
)Berikut adalah contoh kecil tentang mengapa kita harus mengesampingkan
equals()
danhashcode()
.Pertimbangkan
Employee
kelas yang memiliki dua bidang: usia dan nama.Sekarang buat kelas, masukkan
Employee
objek ke dalamHashSet
dan uji apakah objek itu ada atau tidak.Ini akan mencetak yang berikut:
Sekarang
hashcode()
metode uncomment , jalankan hal yang sama dan hasilnya adalah:Sekarang dapatkah Anda melihat mengapa jika dua objek dianggap sama, kode hash mereka juga harus sama? Jika tidak, Anda tidak akan pernah dapat menemukan objek karena metode kode hash default di kelas Object hampir selalu muncul dengan nomor unik untuk setiap objek, bahkan jika
equals()
metode tersebut ditimpa sedemikian rupa sehingga dua atau lebih objek dianggap sama . Tidak masalah seberapa sama objeknya jika kode hash mereka tidak mencerminkan hal itu. Jadi sekali lagi: Jika dua objek sama, kode hash mereka harus sama juga.sumber
Dengan mendefinisikan
equals()
danhashCode()
secara konsisten, Anda dapat meningkatkan kegunaan kelas Anda sebagai kunci dalam koleksi berbasis hash. Seperti dijelaskan API doc untuk hashCode: "Metode ini didukung untuk kepentingan hashtable seperti yang disediakan olehjava.util.Hashtable
."Jawaban terbaik untuk pertanyaan Anda tentang bagaimana menerapkan metode ini secara efisien adalah menyarankan Anda untuk membaca Bab 3 Java Efektif .
sumber
hashCode()
.Sederhananya, metode equals di Object memeriksa persamaan referensi, di mana dua instance kelas Anda masih bisa secara semantik sama ketika propertinya sama. Ini misalnya penting ketika meletakkan objek Anda ke dalam wadah yang menggunakan kode equal dan hash, seperti HashMap dan Set . Katakanlah kita memiliki kelas seperti:
Kami membuat dua instance dengan id yang sama :
Tanpa mengabaikan sama dengan yang kita dapatkan:
Benar? Yah mungkin, jika ini yang Anda inginkan. Tetapi katakanlah kita ingin objek dengan id yang sama menjadi objek yang sama, terlepas dari apakah itu dua contoh yang berbeda. Kami menimpa sama dengan (dan kode hash):
Sedangkan untuk menerapkan equals dan hashcode saya dapat merekomendasikan menggunakan metode pembantu Guava
sumber
Identitas bukanlah kesetaraan.
==
identitas tes operator .equals(Object obj)
metode membandingkan uji kesetaraan (yaitu kita perlu memberi tahu persamaan dengan mengesampingkan metode)Pertama kita harus memahami penggunaan metode equals.
Untuk perbedaan identitas antara dua objek, kita perlu mengganti metode equals.
Sebagai contoh:
Sekarang metode hashCode dapat dimengerti dengan mudah.
hashCode menghasilkan integer untuk menyimpan objek dalam struktur data seperti HashMap , HashSet .
Asumsikan kita memiliki metode override sama
Customer
dengan di atasSaat bekerja dengan struktur data ketika kita menyimpan objek dalam ember (ember adalah nama yang bagus untuk folder). Jika kami menggunakan teknik hash bawaan, untuk di atas dua pelanggan itu menghasilkan dua kode hash yang berbeda. Jadi kita menyimpan objek identik yang sama di dua tempat berbeda. Untuk menghindari masalah seperti ini, kita harus mengganti metode kode hash juga berdasarkan prinsip-prinsip berikut.
sumber
Baiklah, saya jelaskan konsepnya dengan kata-kata yang sangat sederhana.
Pertama dari perspektif yang lebih luas, kami memiliki koleksi, dan hashmap adalah salah satu struktur data dalam koleksi.
Untuk memahami mengapa kita harus mengganti metode equals dan hashcode, jika perlu terlebih dahulu memahami apa itu hashmap dan apa yang dilakukan.
Hashmap adalah struktur data yang menyimpan pasangan nilai kunci data dalam mode array. Katakanlah [], di mana setiap elemen dalam 'a' adalah pasangan nilai kunci.
Juga setiap indeks dalam array di atas dapat ditautkan daftar sehingga memiliki lebih dari satu nilai pada satu indeks.
Sekarang mengapa hashmap digunakan? Jika kita harus mencari di antara array besar kemudian mencari masing-masing jika tidak akan efisien, jadi apa teknik hash memberitahu kita yang memungkinkan pra proses array dengan beberapa logika dan kelompok elemen-elemen berdasarkan pada logika itu yaitu Hashing
misalnya: kami memiliki larik 1,2,3,4,5,6,7,8,9,10,11 dan kami menerapkan fungsi hash mod 10 sehingga 1,11 akan dikelompokkan bersama. Jadi jika kita harus mencari 11 dalam array sebelumnya maka kita harus mengulangi array lengkap tetapi ketika kita mengelompokkannya kita membatasi ruang lingkup iterasi kita sehingga meningkatkan kecepatan. Datastruktur yang digunakan untuk menyimpan semua informasi di atas dapat dianggap sebagai array 2d untuk kesederhanaan
Sekarang selain dari hashmap di atas juga memberi tahu bahwa itu tidak akan menambahkan Duplikat di dalamnya. Dan ini adalah alasan utama mengapa kita harus mengganti kode equals dan hash
Jadi ketika itu mengatakan yang menjelaskan kerja internal hashmap, kita perlu menemukan metode apa yang hashmap miliki dan bagaimana cara mengikuti aturan di atas yang saya jelaskan di atas
sehingga hashmap memiliki metode yang disebut sebagai put (K, V), dan menurut hashmap harus mengikuti aturan di atas untuk mendistribusikan array secara efisien dan tidak menambahkan duplikat apa pun.
jadi apa yang dilakukan adalah bahwa ia pertama-tama akan menghasilkan kode hash untuk kunci yang diberikan untuk memutuskan indeks mana nilai harus masuk. jika tidak ada yang hadir pada indeks itu maka nilai baru akan ditambahkan di sana, jika ada sesuatu yang sudah ada di sana maka nilai baru harus ditambahkan setelah akhir daftar tertaut pada indeks itu. tapi ingat tidak ada duplikat yang harus ditambahkan sesuai perilaku hashmap yang diinginkan. jadi katakanlah Anda memiliki dua objek Integer aa = 11, bb = 11. karena setiap objek berasal dari kelas objek, implementasi standar untuk membandingkan dua objek adalah membandingkan objek dan bukan nilai di dalam objek. Jadi dalam kasus di atas baik secara semantik sama akan gagal tes kesetaraan, dan kemungkinan bahwa dua objek yang memiliki kode hash dan nilai yang sama yang sama akan ada sehingga membuat duplikat. Jika kita menimpanya maka kita dapat menghindari menambahkan duplikat. Anda juga bisa merujukDetail bekerja
sumber
hashCode()
:Jika Anda hanya mengganti metode kode hash, tidak akan terjadi apa-apa. Karena selalu mengembalikan baru
hashCode
untuk setiap objek sebagai kelas Object.equals()
:Jika Anda hanya mengganti metode yang sama,
a.equals(b)
itu benar artinyahashCode
a dan b harus sama tetapi tidak terjadi. Karena Anda tidak menggantihashCode
metode.Catatan:
hashCode()
metode kelas Object selalu mengembalikan yang baruhashCode
untuk setiap objek.Jadi, ketika Anda perlu menggunakan objek Anda di koleksi berbasis hashing, harus menimpa keduanya
equals()
danhashCode()
.sumber
Java menempatkan aturan itu
Jadi, jika di kelas kita kita menimpa
equals()
kita harus menggantihashcode()
metode juga untuk mengikuti aturan ini. Kedua metode,equals()
danhashcode()
, digunakan dalamHashtable
, misalnya, untuk menyimpan nilai sebagai pasangan nilai-kunci. Jika kita menimpa satu dan bukan yang lain, ada kemungkinan bahwaHashtable
mungkin tidak berfungsi seperti yang kita inginkan, jika kita menggunakan objek seperti itu sebagai kunci.sumber
Karena jika Anda tidak menimpanya, Anda akan menggunakan implentasi default di Object.
Mengingat bahwa nilai kesetaraan dan hascode pada umumnya membutuhkan pengetahuan tentang apa yang membuat objek mereka umumnya perlu didefinisikan ulang di kelas Anda untuk memiliki makna yang nyata.
sumber
Untuk menggunakan objek kelas kita sendiri sebagai kunci dalam koleksi seperti HashMap, Hashtable dll., Kita harus mengganti kedua metode (hashCode () dan equals ()) dengan memiliki kesadaran tentang kerja koleksi internal. Kalau tidak, itu mengarah pada hasil yang salah yang tidak kita harapkan.
sumber
Menambah jawaban @Lombo
Kapan Anda perlu mengganti equals ()?
Implementasi default Objects equals () adalah
yang berarti dua objek akan dianggap sama hanya jika mereka memiliki alamat memori yang sama yang hanya akan benar jika Anda membandingkan objek dengan dirinya sendiri.
Tetapi Anda mungkin ingin mempertimbangkan dua objek yang sama jika mereka memiliki nilai yang sama untuk satu atau lebih dari propertinya (Lihat contoh yang diberikan dalam jawaban @Lombo).
Jadi Anda akan mengesampingkan
equals()
dalam situasi ini dan Anda akan memberikan kondisi Anda sendiri untuk kesetaraan.Saya telah berhasil mengimplementasikan equals () dan itu berfungsi dengan baik. Jadi mengapa mereka meminta untuk mengganti kode hash () juga?
Baiklah. Selama Anda tidak menggunakan Koleksi berbasis "Hash" pada kelas yang ditentukan pengguna, tidak apa-apa. Tetapi beberapa waktu di masa depan Anda mungkin ingin menggunakan
HashMap
atauHashSet
dan jika Anda tidakoverride
dan "menerapkan dengan benar" kode kode () , koleksi berbasis Hash ini tidak akan berfungsi sebagaimana dimaksud.Timpa hanya sama dengan (Tambahan untuk jawaban @Lombo)
Pertama-tama, HashMap memeriksa apakah kode hash
second
sama denganfirst
. Hanya jika nilainya sama, ia akan melanjutkan untuk memeriksa kesetaraan dalam ember yang sama.Tapi di sini kode hash berbeda untuk 2 objek ini (karena mereka memiliki alamat memori yang berbeda-dari implementasi standar). Oleh karena itu bahkan tidak akan peduli untuk memeriksa kesetaraan.
Jika Anda memiliki breakpoint di dalam metode override yang sama dengan () Anda, itu tidak akan masuk jika mereka memiliki kode hash yang berbeda.
contains()
memeriksahashCode()
dan hanya jika mereka sama itu akan memanggilequals()
metode Anda .Mengapa kita tidak bisa melakukan pemeriksaan HashMap untuk kesetaraan di semua ember? Jadi tidak ada keharusan bagi saya untuk menimpa kode hash () !!
Maka Anda kehilangan titik Koleksi berbasis Hash. Pertimbangkan yang berikut ini:
Berikut ini adalah kunci-kunci yang disimpan dalam bentuk ember.
Katakan, Anda ingin tahu apakah peta tersebut berisi kunci 10. Apakah Anda ingin mencari semua kotak? atau Apakah Anda ingin mencari hanya satu ember?
Berdasarkan kode hash, Anda akan mengidentifikasi bahwa jika 10 ada, itu harus ada di Bucket 1. Jadi hanya Bucket 1 yang akan dicari !!
sumber
hashCode()
untuk menentukan ember dan menggunakanequals()
metode untuk menemukan apakah nilai tersebut sudah ada dalam Bucket. Jika tidak akan ditambahkan lagi maka akan diganti dengan nilai saat inihashCode()
untuk menemukan Entri (ember) terlebih dahulu danequals()
untuk menemukan nilai dalam Entrijika Keduanya ditimpa,
Peta < A >
jika sama tidak ditimpa
Peta < A >
Jika kode hash tidak diganti
Peta < A >
Kontrak Setara HashCode
sumber
Pertimbangkan koleksi bola dalam ember yang semuanya berwarna hitam. Pekerjaan Anda adalah mewarnai bola-bola itu sebagai berikut dan menggunakannya untuk permainan yang sesuai,
Untuk Tenis - Kuning, Merah. Untuk Cricket - White
Sekarang ember memiliki bola dalam tiga warna Kuning, Merah dan Putih. Dan sekarang Anda melakukan pewarnaan. Hanya Anda yang tahu warna untuk permainan mana.
Mewarnai bola - Hashing. Memilih bola untuk permainan - Sama.
Jika Anda melakukan pewarnaan dan seseorang memilih bola untuk kriket atau tenis, mereka tidak akan keberatan dengan warnanya !!!
sumber
Saya melihat ke penjelasan "Jika Anda hanya menimpa kode hash maka ketika Anda memanggilnya
myMap.put(first,someValue)
butuh lebih dulu, hitung kode hash-nya dan simpan dalam ember yang diberikan. Lalu ketika Anda memanggilnyamyMap.put(first,someOtherValue)
harus ganti dulu dengan yang kedua sesuai Dokumentasi Peta karena mereka sama (sesuai dengan definisi kami). " :Saya pikir waktu ke-2 ketika kita menambahkan
myMap
maka itu harus menjadi objek 'kedua' sepertimyMap.put(second,someOtherValue)
sumber
1) Kesalahan umum ditunjukkan pada contoh di bawah ini.
Mobil hijau tidak ditemukan
2. Masalah yang disebabkan oleh kode hash ()
Masalahnya disebabkan oleh metode un-override
hashCode()
. Kontrak antaraequals()
danhashCode()
adalah:Jika dua objek memiliki kode hash yang sama, mereka mungkin atau mungkin tidak sama.
sumber
Ini berguna saat menggunakan Objek Nilai . Berikut ini adalah kutipan dari Portland Pattern Repository :
sumber
Asumsikan Anda memiliki kelas (A) yang menggabungkan dua lainnya (B) (C), dan Anda perlu menyimpan instance (A) di dalam hashtable. Implementasi default hanya memungkinkan membedakan instance, tetapi tidak dengan (B) dan (C). Jadi, dua contoh A bisa sama, tetapi standar tidak memungkinkan Anda membandingkannya dengan cara yang benar.
sumber
Metode sama dengan dan kode hash didefinisikan dalam kelas objek. Secara default jika metode equals mengembalikan nilai true, maka sistem akan melangkah lebih jauh dan memeriksa nilai kode hash. Jika kode hash dari 2 objek juga sama, maka objek akan dianggap sama. Jadi jika Anda menimpa hanya metode sama dengan, maka meskipun metode sama menimpa menunjukkan 2 objek menjadi sama, sistem kode hash yang ditentukan mungkin tidak menunjukkan bahwa 2 objek sama. Jadi kita perlu mengganti kode hash juga.
sumber
true
untukequals
tidak akan dianggap cocok. Di sisi lain, jika koleksi terjadi perhatikan bahwa sesuatu tidak dapat memiliki kode hash yang sama, mereka cenderung tidak menyadari bahwa mereka sama.Metode Persamaan dan Hashcode di Jawa
Mereka adalah metode kelas java.lang.Object yang merupakan kelas super dari semua kelas (kelas kustom juga dan yang lainnya didefinisikan dalam java API).
Penerapan:
public boolean equals (Object obj)
Metode ini hanya memeriksa apakah dua referensi objek x dan y merujuk ke objek yang sama. Yaitu memeriksa apakah x == y.
Itu refleksif: untuk setiap nilai referensi x, x. sama dengan (x) harus mengembalikan true.
Itu simetris: untuk setiap nilai referensi x dan y, x.equals (y) harus mengembalikan true jika dan hanya jika y.equals (x) mengembalikan true.
Ini transitif: untuk setiap nilai referensi x, y, dan z, jika x.equals (y) mengembalikan true dan y.equals (z) mengembalikan true, maka x.equals (z) harus mengembalikan true.
Ini konsisten: untuk setiap nilai referensi x dan y, beberapa pemanggilan x.equals (y) secara konsisten mengembalikan true atau secara konsisten menghasilkan false, asalkan tidak ada informasi yang digunakan dalam perbandingan yang setara dengan objek yang dimodifikasi.
kode hash int publik ()
Metode ini mengembalikan nilai kode hash untuk objek di mana metode ini dipanggil. Metode ini mengembalikan nilai kode hash sebagai integer dan didukung untuk kepentingan hash kelas koleksi berbasis seperti Hashtable, HashMap, HashSet dll. Metode ini harus diganti di setiap kelas yang menimpa metode equals.
Kontrak umum kode hash adalah:
Setiap kali ia dipanggil pada objek yang sama lebih dari sekali selama eksekusi aplikasi Java, metode kode hash harus secara konsisten mengembalikan integer yang sama, asalkan tidak ada informasi yang digunakan dalam perbandingan yang setara dengan objek yang dimodifikasi.
Bilangan bulat ini tidak harus tetap konsisten dari satu eksekusi aplikasi ke eksekusi aplikasi lainnya yang sama.
Jika dua objek sama menurut metode equals (Objek), maka memanggil metode hashCode pada masing-masing dua objek harus menghasilkan hasil integer yang sama.
Tidak diperlukan bahwa jika dua objek tidak sama menurut metode equals (java.lang.Object), maka memanggil metode hashCode pada masing-masing dua objek harus menghasilkan hasil integer yang berbeda. Namun, programmer harus menyadari bahwa menghasilkan hasil integer yang berbeda untuk objek yang tidak sama dapat meningkatkan kinerja hashtables.
Sumber:
JavaRanch
Gambar
sumber
Dalam contoh di bawah ini, jika Anda mengomentari override untuk sama atau kode hash di kelas Person, kode ini akan gagal untuk mencari pesanan Tom. Menggunakan implementasi standar kode hash dapat menyebabkan kegagalan dalam pencarian hashtable.
Apa yang saya miliki di bawah ini adalah kode sederhana yang menarik pesanan orang oleh Orang. Orang sedang digunakan sebagai kunci dalam hashtable.
sumber
Kelas string dan kelas pembungkus memiliki implementasi
equals()
danhashCode()
metode yang berbeda dari kelas Obyek. equals () metode kelas Object membandingkan referensi objek, bukan isinya. metode hashCode () dari kelas Object mengembalikan kode hash yang berbeda untuk setiap objek apakah isinya sama.Ini menyebabkan masalah ketika Anda menggunakan koleksi Peta dan kuncinya adalah tipe Persistent, tipe StringBuffer / builder. Karena mereka tidak menimpa equals () dan hashCode () tidak seperti kelas String, equals () akan mengembalikan false ketika Anda membandingkan dua objek yang berbeda walaupun keduanya memiliki konten yang sama. Ini akan membuat hashMap menyimpan kunci konten yang sama. Menyimpan kunci konten yang sama berarti melanggar aturan Peta karena Peta sama sekali tidak mengizinkan kunci duplikat. Oleh karena itu Anda mengganti metode equals () dan juga hashCode () di kelas Anda dan memberikan implementasi (IDE dapat menghasilkan metode ini) sehingga mereka bekerja sama dengan String's equals () dan hashCode () dan mencegah kunci konten yang sama.
Anda harus mengganti metode hashCode () bersama dengan equals () karena equals () bekerja sesuai kode hash.
Selain itu meng-overhode metode hashCode () bersama dengan equals () membantu untuk membuat equals () - hashCode () kontrak: "Jika dua objek sama, maka mereka harus memiliki kode hash yang sama."
Kapan Anda perlu menulis implementasi khusus untuk hashCode ()?
Seperti yang kita ketahui bahwa kerja internal HashMap adalah prinsip Hashing. Ada beberapa ember tempat entri disimpan. Anda mengkustomisasi implementasi kode hash () sesuai kebutuhan Anda sehingga objek kategori yang sama dapat disimpan ke dalam indeks yang sama. ketika Anda menyimpan nilai-nilai ke dalam pengumpulan Peta menggunakan
put(k,v)
metode, implementasi internal put () adalah:Berarti, ini menghasilkan indeks dan indeks dihasilkan berdasarkan kode hash objek kunci tertentu. Jadi buat metode ini menghasilkan kode hash sesuai kebutuhan Anda karena entri kode hash yang sama akan disimpan ke dalam ember atau indeks yang sama.
Itu dia!
sumber
hashCode()
Metode digunakan untuk mendapatkan integer unik untuk objek yang diberikan. Bilangan bulat ini digunakan untuk menentukan lokasi bucket, ketika objek ini perlu disimpan di beberapaHashTable
,HashMap
seperti struktur data. Secara default,hashCode()
metode Object mengembalikan dan representasi integer dari alamat memori tempat objek disimpan.The
hashCode()
Metode benda yang digunakan saat kita memasukkan mereka ke dalamHashTable
,HashMap
atauHashSet
. Lebih lanjut tentangHashTables
di Wikipedia.org untuk referensi.Untuk memasukkan entri apa pun dalam struktur data peta, kita membutuhkan kunci dan nilai. Jika kedua kunci dan nilai adalah tipe data yang
hashCode()
ditentukan pengguna, kunci akan menentukan di mana harus menyimpan objek secara internal. Ketika perlu mencari objek dari peta juga, kode hash kunci akan menentukan di mana mencari objek.Kode hash hanya menunjuk ke "area" tertentu (atau daftar, bucket dll) secara internal. Karena objek kunci yang berbeda berpotensi memiliki kode hash yang sama, kode hash itu sendiri bukanlah jaminan bahwa kunci yang tepat ditemukan. The
HashTable
kemudian iterates daerah ini (semua kunci dengan kode hash yang sama) dan menggunakan kunci iniequals()
metode untuk menemukan kunci yang tepat. Setelah kunci kanan ditemukan, objek yang disimpan untuk kunci itu dikembalikan.Jadi, seperti yang bisa kita lihat, kombinasi dari
hashCode()
danequals()
metode digunakan ketika menyimpan dan ketika mencari objek di aHashTable
.CATATAN:
Selalu gunakan atribut yang sama dari objek untuk menghasilkan
hashCode()
danequals()
keduanya. Seperti dalam kasus kami, kami telah menggunakan id karyawan.equals()
harus konsisten (jika objek tidak dimodifikasi, maka ia harus tetap mengembalikan nilai yang sama).Kapanpun
a.equals(b)
, makaa.hashCode()
harus sama denganb.hashCode()
.Jika Anda menimpa satu, maka Anda harus menimpa yang lain.
http://parameshk.blogspot.in/2014/10/examples-of-comparable-comporator.html
sumber
hashCode()
tidak digunakan untuk mengembalikan integer unik untuk setiap objek. Itu tidak mungkin. Anda sendiri telah membantahnya dalam kalimat kedua paragraf keempat.IMHO, sesuai aturan mengatakan - Jika dua objek sama maka mereka harus memiliki hash yang sama, yaitu objek yang sama harus menghasilkan nilai hash yang sama.
Diberikan di atas, default equals () dalam Object adalah == yang melakukan perbandingan pada alamat, hashCode () mengembalikan alamat dalam integer (hash pada alamat aktual) yang lagi berbeda untuk Objek yang berbeda.
Jika Anda perlu menggunakan Objek kustom di koleksi berbasis Hash, Anda harus mengganti sama dengan equals () dan hashCode (), contoh Jika saya ingin mempertahankan HashSet dari Objek Karyawan, jika saya tidak menggunakan kode hash yang lebih kuat dan sama dengan Saya dapat mengakhiri mengesampingkan dua Objek Karyawan yang berbeda, ini terjadi ketika saya menggunakan usia sebagai kode hash (), namun saya harus menggunakan nilai unik yang bisa menjadi ID Karyawan.
sumber
Untuk membantu Anda memeriksa Objek duplikat, kami membutuhkan kode yang sama dengan dan kode hash.
Karena kode hash selalu mengembalikan angka, maka selalu cepat untuk mengambil objek menggunakan angka daripada kunci alfabet. Bagaimana cara kerjanya? Asumsikan kita membuat objek baru dengan melewatkan beberapa nilai yang sudah tersedia di beberapa objek lain. Sekarang objek baru akan mengembalikan nilai hash yang sama dengan objek lain karena nilai yang diteruskan sama. Setelah nilai hash yang sama dikembalikan, JVM akan pergi ke alamat memori yang sama setiap kali dan jika dalam kasus ada lebih dari satu objek hadir untuk nilai hash yang sama akan menggunakan metode equals () untuk mengidentifikasi objek yang benar.
sumber
Ketika Anda ingin menyimpan dan mengambil objek kustom Anda sebagai kunci di Peta, maka Anda harus selalu menimpa sama dengan dan kode hash di Objek kustom Anda. Misalnya:
Di sini p1 & p2 akan dipertimbangkan karena hanya satu objek dan
map
ukuran hanya akan 1 karena keduanya sama.sumber
Kelas Tes
Dalam Object class equals (Object obj) digunakan untuk membandingkan perbandingan alamat, itu sebabnya ketika di kelas Test jika Anda membandingkan dua objek maka sama dengan metode memberi false tetapi ketika kita menimpa kode hash () itu dapat membandingkan konten dan memberikan hasil yang tepat.
sumber
Jika Anda menimpa
equals()
dan tidakhashcode()
, Anda tidak akan menemukan masalah kecuali Anda atau orang lain menggunakan tipe kelas dalam koleksi hash sepertiHashSet
. Orang-orang sebelum saya dengan jelas menjelaskan teori yang didokumentasikan beberapa kali, saya hanya di sini untuk memberikan contoh yang sangat sederhana.Pertimbangkan kelas yang
equals()
kebutuhannya berarti sesuatu yang disesuaikan: -Sekarang pertimbangkan kelas utama ini: -
Ini akan menghasilkan output berikut: -
Saya senang dengan hasilnya. Tetapi jika saya belum menimpa
hashCode()
, itu akan menyebabkan mimpi buruk karena objekRishav
dengan konten anggota yang sama tidak akan lagi diperlakukan sebagai unik karenahashCode
akan berbeda, seperti yang dihasilkan oleh perilaku default, inilah hasilnya: -sumber
Kedua metode didefinisikan dalam kelas Object. Dan keduanya dalam implementasi yang paling sederhana. Jadi ketika Anda membutuhkan Anda ingin menambahkan beberapa implementasi untuk metode ini maka Anda harus menimpa di kelas Anda.
Untuk Ex: equals () metode dalam objek hanya memeriksa kesetaraannya pada referensi. Jadi jika Anda perlu membandingkan kondisinya juga maka Anda dapat menimpanya seperti yang dilakukan dalam kelas String.
sumber
Bah - "Anda harus mengganti kode hash () di setiap kelas yang menimpa sama dengan ()."
[dari Java Efektif, oleh Joshua Bloch?]
Bukankah ini yang salah? Mengganti kode hash kemungkinan menyiratkan Anda sedang menulis kelas hash-key, tetapi mengganti kode hash tentu saja tidak. Ada banyak kelas yang tidak digunakan sebagai kunci hash, tetapi memang menginginkan metode pengujian kesetaraan logis untuk beberapa alasan lain. Jika Anda memilih "sama dengan" untuk itu, Anda kemudian dapat diberi mandat untuk menulis implementasi kode hash dengan penerapan aturan ini secara berlebihan. Semua yang berhasil adalah menambahkan kode yang belum diuji dalam basis kode, kejahatan menunggu seseorang untuk tersandung di masa depan. Juga menulis kode yang tidak Anda butuhkan adalah anti-gesit. Itu hanya salah (dan ide yang dihasilkan mungkin tidak akan sesuai dengan hasil kerajinan tangan Anda).
Tentunya mereka harus mengamanatkan Interface pada objek yang ditulis untuk digunakan sebagai kunci? Apapun, Objek seharusnya tidak menyediakan kode hash () dan equals () imho. Mungkin mendorong banyak koleksi hash yang rusak.
Tapi bagaimanapun, saya pikir "aturan" ditulis kembali ke depan. Sementara itu, saya akan terus menghindari penggunaan "sama dengan" untuk metode pengujian kesetaraan :-(
sumber