Kata pengantar
Seperti yang kita semua tahu, java.lang.Object memiliki metode hashcode () dan equals (), yang memainkan peran penting dalam desain perangkat lunak. Tulis ulang kedua metode ini di beberapa kelas untuk mencapai beberapa fungsi penting.
1. Mengapa menggunakan HashCode ()?
Elemen -elemen dalam set set tidak teratur dan tidak dapat diulang. Jadi apa dasar untuk menilai apakah dua elemen diulang?
Beberapa orang mengatakan: Object.equal() tentu saja digunakan untuk membandingkan apakah objek sama. 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 satu set 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 ini 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.
Ini juga merupakan alasan mengapa ketika Set Set menyimpan data jenis objek, perlu untuk tidak hanya menulis ulang metode hashcode () dari objek tetapi juga menulis ulang metode Equals ().
2. Bagaimana penggunaan hashcode ()?
Hubungan antara nilai pengembalian hashcode () dan 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; @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; }}Metode setara () dan hashcode () digunakan untuk membandingkan di kelas yang sama, terutama saat menyimpan objek kelas yang sama dalam wadah seperti diatur untuk menyimpan objek di kelas yang sama.
Di sini pertama -tama kita perlu memahami masalah:
Dua objek dengan equals () sama, hashCode () harus sama, dan dua objek dengan equals () tidak sama, tidak dapat membuktikan bahwa kode hash mereka tidak sama. Dengan kata lain, untuk dua objek yang metode setara () tidak sama, hashcode () mungkin sama.
Di sini kode hash seperti indeks masing -masing karakter dalam kamus, dan sama () seperti membandingkan kata yang berbeda di bawah karakter yang sama dalam kamus. Sama seperti dalam kamus, mencari dua kata "diri" dan "spontan" di bawah kata "diri" dalam kamus, jika sama () digunakan untuk menentukan kesetaraan permintaan kata, itu adalah kata yang sama. Sebagai contoh, dua kata yang dibandingkan dengan sama () adalah "diri", maka nilai yang diperoleh dengan metode hashcode () harus sama pada saat ini; Jika metode Equals () membandingkan kata -kata "diri" dan "spontan", maka hasilnya adalah Anda tidak ingin menunggu, tetapi kedua kata ini milik kata "diri" dan ketika mencari indeks, yaitu, hashcode () adalah sama. Jika sama () membandingkan kata "diri" dan "mereka", maka hasilnya juga berbeda, dan hasil yang diperoleh dengan kode hashcode () juga berbeda pada saat ini.
Sebaliknya: HashCode () berbeda, dan setara () dapat diperkenalkan; HashCode () sama, sama () mungkin sama atau mungkin tidak sama.
Di kelas objek, metode hashcode () adalah metode lokal, yang mengembalikan nilai alamat objek. Metode Equals () di kelas objek juga membandingkan nilai alamat dari dua objek. Jika sama () sama, itu berarti bahwa nilai alamat dari kedua objek juga sama. Tentu saja, hashCode () sama.
Karena sama dengan lebih akurat untuk membandingkan elemen yang sama, mengapa menggunakan metode hashcode ()?
Karena algoritma hash memberikan efisiensi tinggi dalam menemukan elemen, jika Anda ingin menemukan apakah koleksi berisi suatu objek, cara menulis kode program perkiraan?
Anda biasanya mengambil setiap elemen satu per satu untuk membandingkan dengan objek yang Anda cari. Ketika Anda menemukan bahwa hasil dari perbandingan metode yang sama antara suatu elemen dan objek yang Anda cari, berhenti mencari dan mengembalikan informasi positif. Jika tidak, kembalikan informasi negatif. Jika ada banyak elemen dalam koleksi, seperti 10.000 elemen dan tidak mengandung objek yang Anda cari, itu berarti bahwa program Anda perlu mengambil 10.000 elemen dari koleksi dan membandingkan satu per satu untuk mendapatkan kesimpulan.
Kelas Objek mendefinisikan metode hashcode () untuk mengembalikan kode hash setiap objek Java. Saat mencari objek dari koleksi hashset, sistem Java pertama -tama memanggil metode hashcode () objek untuk mendapatkan tabel kode hash objek, dan kemudian menemukan area penyimpanan yang sesuai berdasarkan hash, dan akhirnya memperoleh setiap elemen di area penyimpanan dan membandingkannya dengan objek untuk metode Equals. Dengan cara ini, Anda bisa mendapatkan kesimpulan tanpa melintasi semua elemen dalam koleksi. Dapat dilihat bahwa koleksi hashset memiliki kinerja pengambilan objek yang baik.
Namun, efisiensi menyimpan objek dalam koleksi hashset relatif rendah, karena ketika menambahkan objek ke koleksi hashset, kode hash objek harus dihitung terlebih dahulu dan lokasi penyimpanan objek dalam koleksi ditentukan berdasarkan kode hash ini. Untuk memastikan bahwa objek instance dari suatu kelas dapat disimpan secara normal dalam hashset, hasil dari dua objek instance dari kelas ini harus sama bila dibandingkan dengan metode Equals () sama; yaitu, jika hasil obj1.equals(obj2) benar, maka hasil dari ekspresi berikut juga harus true:obj1.hashCode() == obj2.hashCode() .
Dengan kata lain: Ketika kita menulis ulang metode yang setara dengan objek, kita harus menulis ulang metode kode hash -nya. Jika kita tidak menulis ulang metode kode hash -nya, metode kode hashcode dalam objek selalu mengembalikan alamat hash suatu objek, dan alamat ini tidak pernah sama. Jadi, bahkan jika metode Equals ditulis ulang saat ini, tidak akan ada efek khusus, karena jika metode kode hash tidak ingin menunggu, itu tidak akan memanggil metode Equals untuk perbandingan, sehingga tidak ada artinya.
Sebagian besar struktur data menggunakan metode Equals untuk menentukan apakah mereka berisi elemen, misalnya:
Daftar <string> list = arrays.aslist ("a", "b", "c"); boolean berisi = list.contains ("b"); Variabel ini berisi hasil yang benar karena, meskipun "B" adalah contoh yang berbeda (selain itu, residensi string diabaikan), mereka sama.
Mereka menggunakan cara cepat untuk membandingkan (mengurangi kesetaraan instance potensial) alih -alih membandingkan setiap elemen yang terkandung dalam instance. Perbandingan cepat hanya membutuhkan membandingkan aspek -aspek berikut:
Perbandingan jalan pintas berarti bahwa dengan membandingkan nilai hash, ia dapat menggantikan instance dengan nilai integer. Contoh dengan kode hash yang sama tidak harus sama, tetapi contoh dengan kesetaraan harus memiliki nilai hash yang sama. (atau seharusnya, kita akan membahas hal ini segera) Struktur data ini sering dinamai oleh teknik ini, dan mereka dapat diidentifikasi dengan hash, di antaranya hashmap adalah perwakilan yang paling terkenal.
Mereka biasanya bekerja seperti ini:
Saat menambahkan elemen, kode hashnya digunakan untuk menghitung indeks array internal (yaitu, yang disebut ember)
Jika ya, elemen yang tidak setara memiliki kode hash yang sama, mereka berakhir dengan ember yang sama dan dibundel bersama, misalnya dengan menambahkan ke daftar.
Ketika sebuah instance berkinerja berisi operasi, kode hashnya akan digunakan untuk menghitung nilai bucket (nilai indeks), dan instance akan dibandingkan hanya ketika elemen ada pada nilai indeks yang sesuai.
Oleh karena itu sama, kode hash didefinisikan dalam kelas objek.
Jika kode hash digunakan sebagai jalan pintas untuk menentukan kesetaraan, maka hanya ada satu hal yang harus kita pedulikan: objek yang sama harus memiliki kode hash yang sama, itulah sebabnya jika kita mengganti metode yang sama, kita harus membuat implementasi kode hash yang cocok dengan itu!
Jika tidak, objek yang sama mungkin tidak memiliki kode hash yang sama, karena mereka akan memanggil implementasi default objek.
Kutipan dari dokumen resmi
Konvensi Umum HashCode:
Saat memanggil objek yang sama berjalan dalam aplikasi Java, metode kode hashcode harus selalu mengembalikan bilangan bulat yang sama. Integer ini tidak perlu konsisten di berbagai aplikasi Java. Menurut metode equals(Object) , jika dua objek sama, kedua objek memanggil metode HashCode harus menghasilkan hasil yang sama.
Menurut metode equals(Object) , jika kedua objek tidak sama, maka memanggil metode HashCode tidak selalu menghasilkan hasil integer yang berbeda. Namun, pemrogram harus menyadari bahwa menghasilkan hasil integer yang berbeda untuk objek yang tidak setara kemungkinan akan meningkatkan kinerja tabel hash.
Implementasi HashCode
Berikut adalah implementasi sederhana dari person.hashcode() :
@Overridepublic int hashCode () {return objects.hash (firstName, lastName);}Orang menghitung kode hash orang dengan menggabungkan beberapa bidang. Semua dihitung oleh fungsi hash objek.
Pilih bidang
Tapi bidang mana yang terkait? Persyaratan akan membantu kami menjawab pertanyaan ini:
Jika objek yang sama harus memiliki kode hash yang sama, kode hash yang dihitung tidak boleh menyertakan bidang apa pun yang tidak digunakan untuk pemeriksaan kesetaraan. (Jika tidak, kedua objek hanya bahwa bidang -bidang ini berbeda tetapi mereka mungkin masih sama, tetapi kode hash dari kedua objek akan berbeda pada saat ini.) Jadi subset dari bidang yang digunakan ketika bidang kelompok hash harus sama. Bidang yang sama digunakan secara default, tetapi ada beberapa detail yang perlu dipertimbangkan.
Meringkaskan
Kami memahami bahwa menghitung kode hash adalah untuk mengompres nilai integer yang sama: Objek yang sama harus memiliki kode hash yang sama, dan untuk pertimbangan kinerja, yang terbaik adalah berbagi kode hash yang sama dengan sedikit mungkin objek yang tidak setara.
Ini berarti bahwa jika metode yang sama ditulis ulang, maka metode kode hashcode harus ditulis ulang.
Saat mengimplementasikan kode hash menggunakan bidang yang sama seperti yang digunakan dalam setara (atau subset bidang yang digunakan secara setara)
Yang terbaik adalah tidak memasukkan bidang yang bisa berubah. Jangan pertimbangkan untuk menelepon kode hash untuk koleksi. Jika tidak ada mode spesifik input khusus, cobalah untuk menggunakan algoritma hash umum.
Oke, di atas adalah seluruh konten artikel ini. Saya berharap konten artikel ini memiliki nilai referensi tertentu untuk studi atau pekerjaan semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi. Terima kasih atas dukungan Anda ke wulin.com.