Sarà una lunga risposta, prendi un drink e continua a leggere ...
L'hashing consiste nel memorizzare una coppia chiave-valore in memoria che può essere letta e scritta più velocemente. Memorizza le chiavi in un array e i valori in un LinkedList.
Diciamo che voglio memorizzare 4 coppie chiave-valore -
{
“girl” => “ahhan” ,
“misused” => “Manmohan Singh” ,
“horsemints” => “guess what”,
“no” => “way”
}
Quindi per memorizzare le chiavi abbiamo bisogno di un array di 4 elementi. Ora come posso mappare una di queste 4 chiavi su 4 indici di array (0,1,2,3)?
Quindi java trova l'hashCode delle singole chiavi e le associa a un particolare indice di array. Hashcode Formulas è -
1) reverse the string.
2) keep on multiplying ascii of each character with increasing power of 31 . then add the components .
3) So hashCode() of girl would be –(ascii values of l,r,i,g are 108, 114, 105 and 103) .
e.g. girl = 108 * 31^0 + 114 * 31^1 + 105 * 31^2 + 103 * 31^3 = 3173020
Hash and girl !! So cosa stai pensando. Il tuo fascino per quel duetto selvaggio potrebbe farti perdere una cosa importante.
Perché java lo moltiplica per 31?
È perché, 31 è un numero primo dispari nella forma 2 ^ 5 - 1. E il primo dispari riduce la possibilità di Hash Collision
Ora come viene mappato questo codice hash su un indice di array?
risposta è Hash Code % (Array length -1)
. Quindi “girl”
è mappato (3173020 % 3) = 1
nel nostro caso. che è il secondo elemento dell'array.
e il valore "ahhan" è memorizzato in un LinkedList associato all'indice di array 1.
HashCollision - Se provi a trovare hasHCode
le chiavi “misused”
e “horsemints”
usando le formule sopra descritte vedrai entrambi darci lo stesso 1069518484
. Whooaa !! lezione imparata -
2 oggetti uguali devono avere lo stesso hashCode ma non vi è alcuna garanzia se l'hashCode corrisponde quindi gli oggetti sono uguali. Quindi dovrebbe archiviare entrambi i valori corrispondenti a "abuso" e "horsemints" nel bucket 1 (1069518484% 3).
Ora la mappa hash sembra:
Array Index 0 –
Array Index 1 - LinkedIst (“ahhan” , “Manmohan Singh” , “guess what”)
Array Index 2 – LinkedList (“way”)
Array Index 3 –
Ora se qualche body prova a trovare il valore per la chiave “horsemints”
, java troverà rapidamente l'hashCode di esso, lo modellerà e inizierà a cercare il suo valore nella LinkedList corrispondente index 1
. Quindi in questo modo non è necessario cercare tutti i 4 indici dell'array, rendendo così più veloce l'accesso ai dati.
Ma aspetta un secondo. ci sono 3 valori in quel LinkedList corrispondente all'indice Array 1, come scopre quale era il valore per i "parametri" chiave?
In realtà ho mentito, quando ho detto che HashMap memorizza i valori in LinkedList.
Memorizza entrambe le coppie chiave-valore come voce della mappa. Quindi in realtà la mappa è simile a questa.
Array Index 0 –
Array Index 1 - LinkedIst (<”girl” => “ahhan”> , <” misused” => “Manmohan Singh”> , <”horsemints” => “guess what”>)
Array Index 2 – LinkedList (<”no” => “way”>)
Array Index 3 –
Ora puoi vedere Mentre attraversi l'Elenco collegato corrispondente ad ArrayIndex1, in realtà confronta la chiave di ciascuna voce di quell'Elenco collegato con i "nodi" e quando ne trova uno restituisce semplicemente il valore di esso.
Spero ti sia divertito a leggerlo :)