Perhitungan hash adalah untuk menghitung elemen mana yang harus ditempatkan dalam array. Tepatnya, itu diletakkan di mana daftar tautan. Menurut aturan Java, jika Anda ingin memasukkan objek ke dalam hashmap, kelas objek Anda harus memberikan metode kode hash dan mengembalikan nilai integer. Misalnya, kelas string memiliki metode berikut:
public int hashCode () {int h = hash; int len = hitung; if (h == 0 && len> 0) {int off = offset; char val [] = nilai; untuk (int i = 0; i <len; i ++) {h = 31*h+val [OFF ++]; } hash = h; } return h; } Perhatikan loop untuk di atas, bukankah itu sedikit kacau? Izinkan saya memberi Anda contoh sehingga mudah untuk memahami apa yang dibuatnya. Misalnya, ada string "ABCDE" yang menggunakan metode perhitungan 31 digit untuk menghitung jumlah string ini. Anda akan menulis formula perhitungan berikut:
A*31^4+B*31^3+C*31^2+D*31^1+E*31^0. Perhatikan bahwa a, b, c, d atau e di sini merujuk pada nilai ASCII mereka. Loop yang sangat menarik, yang dapat digunakan untuk menghitung n-digit. Loop ini dapat diekstraksi secara terpisah sebagai alat yang baik untuk menghitung partisi:
public static void main (string [] args) {int [] a = {1,0}; System.out.println (Hitung (2, A)); } private static int calculate (int radix, int [] a) {int sum = 0; untuk (int i = 0; i <a.length; ++ i) {sum = sum*radix+a [i]; } return sum; } Caculate metode statis menerima radix sebagai kardinalitas, dan array A mensimulasikan jumlah penghitungan yang akan dihitung, cukup perhatikan urutan permukaan yang konsisten. Misalnya, string biner 01 harus diatur dalam array sesuai dengan {0,1}. Output di atas adalah 1, yang memenuhi nilai sebenarnya dari 01.
Jadi mengapa menggunakan 31 sebagai pangkalan? Pertama, Anda perlu memahami mengapa kode hash dibutuhkan. Setiap objek menghitung kode hash berdasarkan nilai. Meskipun ukuran kode ini tidak memerlukan keunikan (karena ini biasanya akan sangat lambat), harus sebanyak mungkin dan tidak diulang mungkin, sehingga kardinalitas harus sebesar mungkin. Selain itu, 31*n dapat dioptimalkan oleh kompiler untuk bergeser dengan 5 bit dan kemudian dikurangi dengan 1, yang memiliki kinerja yang lebih tinggi. Bahkan, masih kontroversial untuk memilih 31, silakan merujuk di sini.
Saya pikir hal ini masih akan menyebabkan lebih banyak pengulangan dan harus menggunakan angka yang lebih besar. Jadi, mungkin ada beberapa perubahan dalam implementasi Java di masa depan. Artikel berikut memperkenalkan dua kesimpulan:
1. Gunakan bilangan prima untuk kardinalitas
Karakteristik bilangan prima (hanya 1 dan itu sendiri adalah faktor) yang dapat membuat hasil yang diperoleh dengan mengalikannya dengan bilangan lain lebih mudah untuk menghasilkan keunikan daripada metode lain, yaitu, probabilitas konflik antara nilai kode hash adalah yang terkecil.
2. Pilihan 31 adalah pilihan setelah mengamati hasil distribusi. Alasannya tidak jelas, tetapi memang bermanfaat.
Selain itu, nilai yang dihitung pertama akan di -cache secara internal, karena ini adalah kelas final (tidak dapat diubah), yaitu, konten dari objek string tidak akan berubah. Ini dapat meningkatkan kinerja saat menempatkan hashmap beberapa kali, tetapi tampaknya tidak banyak berguna.
Meringkaskan
Di atas adalah semua tentang alasan mengapa 31 koefisien digunakan saat mendefinisikan kode hash. Saya harap ini akan membantu semua orang. Teman yang tertarik dapat terus merujuk ke situs ini:
" Pengantar terperinci untuk menulis ulang metode hashcode () dan setara () "
" Penjelasan terperinci tentang perbedaan esensial dan koneksi antara hashcode () dan Equals () "
" Analisis Kode Sumber Java Penggunaan Hashmap "
Jika ada kekurangan, silakan tinggalkan pesan untuk menunjukkannya. Terima kasih teman atas dukungan Anda untuk situs ini!