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 ()?
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.
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.
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.
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.