Was ist der bevorzugte Weg zur Implementierung von hashCode ()?

8

Manchmal muss ich die hashCode () -Methode eines Objekts implementieren, indem ich die hashCodes seiner verschiedenen Instanzmitglieder kombiniere. Zum Beispiel, wenn das kombinatorische Objekt die Mitglieder a, b und c hat, sehe ich oft, dass es als

implementiert wird %Vor%

Woher kommt diese magische Zahl 31? Ist es die Länge von 4 Bytes oder nur eine Primzahl?

Gibt es einen anderen bevorzugten / standardmäßigen Weg zur Implementierung von hashCode ()?

    
dolaameng 06.10.2010, 03:06
quelle

6 Antworten

8

Siehe Effektives Java-Rezept . Es ist einfach die beste Quelle, die Hände runter.

Die Verwendung einer Primzahl dient nur dazu, eine einigermaßen gute Verteilung zu erreichen, ohne die Domain zu kennen. Es wird eine Weile dauern, bis der gleiche Wert erreicht ist. Der Wert 31 ist ziemlich willkürlich, wenn ich mich richtig erinnere.

Nach Bloch (er benutzt 17 als Anfangswert und 37 als konstanten Multiplikator):

  

Ein Anfangswert ungleich Null wird verwendet (...), so dass der Hash-Wert beeinflusst wird   Anfangsfelder, deren Hash-Wert (...) Null ist. Wenn Null als verwendet wurde   der anfängliche Wert (...) würde der gesamte Hash-Wert von einem solchen nicht beeinflusst werden   Anfangsfelder, die Kollisionen erhöhen könnten. Der Wert 17 ist beliebig.
  ...
  Der Multiplikator 37 wurde gewählt, weil er eine ungerade Primzahl ist. Wenn es war und   die Multiplikation ist übergelaufen, die Information würde verloren gehen, weil es multipliziert wird   um zwei entspricht dem Verschieben. Die Vorteile der Verwendung einer Primzahl sind geringer   klar, aber es ist üblich, Primzahlen für diesen Zweck zu verwenden.

    
Mark Peters 03.04.2014, 11:04
quelle
6

Eine gute Option ist die Guava Methode Objects.hashCode . Es benötigt eine beliebige Anzahl von Argumenten und erstellt einen darauf basierenden Hashcode:

%Vor%     
ColinD 06.10.2010 03:51
quelle
2

Benutze HashCodeBuilder von Commons Lang:

%Vor%

Sehen Sie in der API nach Möglichkeiten, dies ohne Reflektion zu tun. Sie können angeben, welche Felder einbezogen werden sollen oder welche ignoriert werden sollen.

Siehe auch EqualsBuilder zum Überschreiben einer equals-Methode.

    
wmorgan 06.10.2010 03:21
quelle
1

Generiere es mit deiner IDE.

    
Michael Barker 06.10.2010 05:41
quelle
0

Grundsätzlich sollte Ihr Hash-Code aus dem Schlüsselparameter Ihres POJO bestehen. Ein Beispiel ist unten.

%Vor%

Im obigen Beispiel sind die Roll-ID und der Name die Schlüsselparameter dieses POJO.

Es ist eine gute Übung, wenn Sie nur die Parameter in die hashCode-Methode einfügen, die Sie in der Eqauls-Methode desselben POJO hinzufügen.

    
M.J. 06.10.2010 04:18
quelle
0

Ich glaube, das Folgende ist eine gute Übung für einfache Szenarien: Wenn Ihre Klasse schreibgeschützte Mitglieder enthält, wären sie gute Kandidaten, um den Hashcode des Objekts zu generieren. Wenn Ihre Klasse jedoch nur die mutierenden Elemente enthält, können Sie ein schreibgeschütztes int-Feld erstellen, das den Wert basierend auf den Nicht-Null-Werten erhält, die an den Konstruktor übergeben werden.

    
Mahorad 20.03.2014 08:51
quelle

Tags und Links