Die Hash -Berechnung besteht darin, zu berechnen, welches Element im Array platziert werden soll. Um genau zu sein, wird es in welche Linkliste gesetzt. Nach den Java -Regeln muss die Klasse Ihres Objekts eine HashCode -Methode bereitstellen und einen Ganzzahlwert zurückgeben, wenn Sie ein Objekt in eine HashMap einfügen möchten. Beispielsweise hat die String -Klasse die folgenden Methoden:
public int hashcode () {int h = hash; int len = count; if (h == 0 && len> 0) {int off = offset; char val [] = Wert; für (int i = 0; i <len; i ++) {H = 31*H+val [off ++]; } Hash = H; } return h; } Achten Sie auf die für die Schleife oben, ist es nicht ein bisschen durcheinander? Lassen Sie mich Ihnen ein Beispiel geben, damit es leicht zu verstehen ist, was es macht. Beispielsweise gibt es eine Zeichenfolge "ABCDE", die eine 31-stellige Berechnungsmethode verwendet, um die Summe dieser Zeichenfolge zu berechnen. Sie werden die folgende Berechnungsformel schreiben:
a*31^4+b*31^3+c*31^2+d*31^1+e*31^0. Beachten Sie, dass sich A, B, C, D oder E hier auf ihre ASCII -Werte beziehen. Sehr interessante Schleifen, mit denen N-Digit berechnet werden kann. Diese Schleife kann separat als gutes Werkzeug zur Berechnung der Partition extrahiert werden:
public static void main (String [] args) {int [] a = {1,0}; System.out.println (berechnen (2, a)); } private static int calculate (int radix, int [] a) {int sum = 0; für (int i = 0; i <A.Length; ++ i) {sum = sum*radix+a [i]; } Return Sum; } Das statische Methode Caculat akzeptiert Radix als Kardinalität und simuliert die Anzahl der zu berechnenden Berechnung, achten Sie nur auf die konsistente Oberflächenreihenfolge. Beispielsweise sollte die 01 -Binärzeichenfolge im Array gemäß {0,1} angeordnet werden. Die obige Ausgabe ist 1, der den wahren Wert von 01 entspricht.
Warum also 31 als Basis verwenden? Zunächst müssen Sie verstehen, warum Hashcode benötigt wird. Jedes Objekt berechnet HashCode basierend auf dem Wert. Obwohl diese Codegröße keine Einzigartigkeit erfordert (da dies normalerweise sehr langsam ist), sollte sie so weit wie möglich und nicht wie möglich wiederholt sein, sodass die Kardinalität so groß wie möglich sein sollte. Zusätzlich kann 31*n vom Compiler optimiert werden, dass sie um 5 Bits links verlagert und dann um 1 reduziert werden, was eine höhere Leistung aufweist. Tatsächlich ist es immer noch kontrovers, 31 zu wählen. Weitere Informationen finden Sie hier.
Ich denke, dieses Ding wird immer noch zu mehr Wiederholungen führen und sollte größere Zahlen verwenden. Vielleicht gibt es in Zukunft möglicherweise einige Änderungen in der Java -Implementierung. Der folgende Artikel führt zwei Schlussfolgerungen vor:
1. Verwenden Sie Primzahlen für die Kardinalität
Die Eigenschaften von Primzahlen (nur 1 und sich selbst sind Faktoren) können das Ergebnis machen, das durch Multiplizieren mit anderen Zahlen eine Einzigartigkeit leichter als andere Methoden erzeugt wird, dh die Wahrscheinlichkeit eines Konflikts zwischen Hash -Code -Werten ist die kleinste.
2. Auswahl 31 ist eine Wahl nach der Beobachtung der Verteilungsergebnisse. Der Grund ist nicht klar, aber es ist in der Tat vorteilhaft.
Darüber hinaus wird der erste berechnete Wert intern zwischengespeichert, da dies eine endgültige (unveränderliche) Klasse ist, dh der Inhalt des String -Objekts ändert sich nicht. Dies kann die Leistung verbessern, wenn HashMap mehrmals eingesetzt wird, aber es scheint wenig nützlich zu sein.
Zusammenfassen
Bei der oben genannten Gründe geht es um die Gründe, warum bei der Definition von HashCode 31 Koeffizienten verwendet werden. Ich hoffe, es wird für alle hilfreich sein. Interessierte Freunde können weiterhin auf diese Seite verweisen:
" Detaillierte Einführung in den Umschreiben von HashCode () und Equals () Methoden "
" Detaillierte Erläuterung der wesentlichen Unterschiede und Verbindungen zwischen HashCode () und Equals () "
" Java -Quellcodeanalyse der HashMap -Verwendung "
Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!