Zunächst einmal: Wofür wird die Hash-Methode verwendet?
Bevor wir das Prinzip verstehen, stellen wir uns zunächst auf die Schultern der Giganten und verstehen kurz die wesentliche Funktion der Hash-Methode.
Im Wesentlichen ist seine Funktion sehr einfach, nämlich den Schlüsselwert zu verwenden, um auf irgendeine Weise einen Hash-Code zu berechnen.
Und dieser Hash-Code wird später verwendet, um den Index des zugrunde liegenden Arrays zu berechnen, in dem der Schlüssel vorhanden ist. Daher muss ein gewisser Grad an Zufälligkeit beibehalten werden, um die berechneten Array-Element-Indizes gleichmäßiger zu verteilen und Kollisionen zu reduzieren, was eigentlich dazu dient, sie zu vermeiden in einem größeren Ausmaß. Hash-Konflikt.
Hinweis: Die Eigenschaft der Aufrechterhaltung der Zufälligkeit spiegelt sich nur im Schritt der Berechnung des Hash-Werts mithilfe der Hash-Methode wider. Die anschließende Modulo-Operation dient nur der Ermittlung des Rests und hat nichts mit der Sicherstellung der Zufälligkeit zu tun.
Was ist die Hash-Methode?
Hier ist der Quellcode intuitiv:
Diese kurze Codezeile vereint den Einfallsreichtum vieler Computergiganten.Theoretisch ist der Hash-Wert (dh der von der Hashcode-Methode zurückgegebene Wert) ein int- Typ. Jeder weiß, dass der int-Typ in Java 4 Bytes, also 32 Bits, im Bereich von -2147483648 bis 2147483648 belegt . Der gesamte Zuordnungsraum beträgt etwa 4 Milliarden. Solange die Hash-Werte relativ gleichmäßig und locker zugeordnet werden, kommt es im Allgemeinen zu keinen Hash-Kollisionen (Hash-Konflikte verringern die Effizienz von HashMap).Das Problem besteht jedoch darin, dass ein Array mit einer Länge von 4 Milliarden nicht in den Speicher passt. Die anfängliche Größe des Arrays vor der HashMap- Erweiterung betrug nur 16 , daher kann dieser Hash-Wert nicht direkt verwendet werden. Bevor Sie ihn verwenden, müssen Sie eine Modulo-Operation mit der Länge des Arrays ((n - 1) & Hash wie oben erwähnt) durchführen. , und Sie können den Rest verwenden, um auf den Array-Index zuzugreifen.
Wie ist h ^ h>>>16 zu verstehen?
Das h oben ist eigentlich der Hashcode-Wert, den wir durch Aufrufen der hashcode()-Methode des Schlüssels erhalten. Wir verschieben ihn um 16 Bit nach rechts (da es sich um einen int-Typ handelt, also insgesamt 32 Bit) und füllen den ersten Wert aus 16 Bits mit 0, und dann machen wir es mit dem Original gleich. Der Hashcode-Wert wird XOR-verknüpft, da sich die Logik von XOR von 1 unterscheidet, was den ersten 16 Bits entspricht, und die letzten 16 Bits werden einmal XOR-verknüpft und belegen Die 16 aufgefüllten Nullen werden XOR-verknüpft und belegen die ersten 16 Bits des endgültig zurückgegebenen Hash. Der endgültig zurückgegebene Hash-Code wird erhalten.
Der obige Prozess kann anhand der folgenden Abbildung betrachtet werden:
Auf diese Weise sind Sie möglicherweise verwirrt. Was ist der Grund für dieses Hin- und Hergehen? Tatsächlich hat alles eine Sache: die Zufälligkeit des Hash-Codes, und der Zweck besteht darin, Hash-Konflikte zu vermeiden. Schließlich Hash-Konflikte verringern die Effizienz von HashMap.
Wie verwenden wir nach der Berechnung des Hash-Werts den Hash-Wert zur Berechnung des Index?
Wir verwenden (n - 1) & Hash, um den Index zu erhalten; (eigentlich ist es eine Modulo-Operation)
Sie sind vielleicht neugierig: Sollten Sie nicht % verwenden, um Modulo-Operationen auszuführen? Warum die bitweise Operation & verwenden ?
Dies liegt daran, dass % zwar tatsächlich erreicht werden kann, der tatsächliche Wirkungsgrad jedoch immer noch nicht so gut ist wie &
Und unser & kann % ersetzen, es gibt eine Voraussetzung:
Nur wenn b 2 in der n-ten Potenz ist , gibt es eine solche Formel: a % b = a & (b-1 )
Wir können es überprüfen:
Lassen Sie es uns überprüfen, wenn a = 14 , b = 8 , also 2^3 , n=3 .14%8 (Rest ist 6), das Binärsystem von 14 ist 1110 , das Binärsystem von 8 ist 1000 , 8-1 = 7 , das Binärsystem von 7 ist 0111 , 1110&0111=0110 , also 0 * 2^ 0+1 * 2^1+ 1 * 2^2+0 * 2 ^3=0+2+4+0=6 , 14%8 ist genau gleich 6 .Verdammt, Computer sind einfach so vernünftig, dass man nichts dagegen tun kann
Schauen wir uns im Anschluss an das Diagramm der vorherigen Frage diesen Schritt an, um zu verstehen:
Nachdem wir das Prinzip der Hash-Methode kennen und berechnen, müssen wir auch Folgendes wissen:
Wo wird die Hash-Methode verwendet?
1. Die erste ist natürlich unsere klassischste Put-Methode. Der nachfolgende Putval berechnet den Index anhand des Hash-Werts.
2. Zweitens rufen wir, wenn wir die get-Methode verwenden, um ein Element abzurufen, die getNode-Methode auf, die den Hash-Wert verwendet.