Untuk memperluas jawaban David Richerby, istilah " fungsi hash " sedikit kelebihan. Seringkali, ketika kita berbicara tentang fungsi hash kita memikirkan MD5, SHA-1, atau sesuatu seperti .hashCode()
metode Java , yang mengubah beberapa input menjadi satu nomor. Namun domain nomor ini (yaitu nilai maksimum) sangat tidak mungkin memiliki ukuran yang sama dengan hashtable yang Anda coba simpan data. (MD5 adalah 16 byte, SHA-1 adalah 20 byte, dan .hashCode()
merupakan int
- 4 byte).
Jadi pertanyaan Anda adalah tentang langkah selanjutnya - setelah kami memiliki fungsi hash yang dapat memetakan input sewenang-wenang ke angka, bagaimana kita menempatkan mereka ke dalam struktur data dengan ukuran tertentu? Dengan fungsi lain, juga disebut "fungsi hash"!
Contoh sepele dari fungsi tersebut adalah modulo ; Anda dapat dengan mudah memetakan sejumlah ukuran acak ke indeks tertentu dalam array dengan modulo. Ini diperkenalkan dalam CLRS sebagai "metode pembagian":
Dalam metode pembagian untuk membuat fungsi hash, kami memetakan kunci ke salah satu slot dengan mengambil sisa dibagi dengan . Artinya, fungsi hash adalahm k mkmkm
mh(k)=k mod .m
...
Saat menggunakan metode pembagian, kita biasanya menghindari nilai tertentu . Misalnya, tidak harus menjadi kekuatan 2, karena jika maka hanyalah terendah-order bit .m m = 2 p h ( k ) p kmmm=2ph(k)pk
~ Pengantar Algoritma, §11.3.1 - CLRS
Jadi modulo bukanlah fungsi hash yang hebat, karena modulo membatasi ukuran apa yang dapat kita gunakan dengan aman untuk struktur data dasar kita. Bagian berikutnya memperkenalkan "metode multiplikasi" yang sedikit lebih kompleks, yang juga menggunakan modulo tetapi menguntungkan karena "nilai tidak kritis". Namun itu bekerja paling baik dengan pengetahuan sebelumnya tentang "karakteristik data yang di-hash" - sesuatu yang sering kita tidak tahu.m
Java HashMap
menggunakan versi modifikasi dari metode pembagian yang melakukan langkah pra-pemrosesan untuk menjelaskan .hashCode()
implementasi yang lemah sehingga dapat menggunakan array berukuran dua kekuatan. Anda dapat melihat dengan tepat apa yang terjadi dalam .getEntry()
metode ini (komentar adalah milik saya):
// hash() transforms key.hashCode() to protect against bad hash functions
int hash = (key == null) ? 0 : hash(key.hashCode());
// indexOf() converts the resulting hash to a value between 0 and table.length-1
for (Entry<K,V> e = table[indexFor(hash, table.length)];
...
Java 8 membawa serta penulisan ulang HashMap
yang bahkan lebih cepat, tetapi sedikit lebih sulit untuk dibaca. Namun, ia menggunakan prinsip umum yang sama untuk pencarian indeks.