8
votes

Quel est le moyen préféré de mettre en œuvre HashCode ()?

Parfois, j'ai besoin de mettre en place une méthode HashCode () d'Obj en combinant les Hashcodes de ses nombreux membres d'instance. Par exemple, si l'OBJ combinant a des membres A, B et C, je vois souvent la PPL l'implémenter comme xxx

où provient-il de ce numéro de magie? Est-ce la longueur de 4 octets ou juste un nombre premier?

y a-t-il d'autre manière préférée / standard de mise en œuvre de hashcode ()?


2 commentaires

Similaire (mais pas nécessairement dupliquer): Stackoverflow.com/Questtions/3613102/...


Le Prime 31 est utilisé dans string.hashcode () Cela permet de faire de bon qualité car il n'y a pas beaucoup de caractères possibles, mais j'ai tendance à utiliser des grands nombres premiers. Un bon site pour "intéressant" Primes est prime.utm.edu/curios


6 Réponses :


8
votes

voir Recette de Java 'efficace . C'est juste la meilleure source, la main vers le bas.

L'utilisation d'un nombre premier est juste d'essayer d'obtenir une distribution raisonnablement bonne sans connaître le domaine. Il faudra un certain temps pour déborder à la même valeur. La valeur 31 est assez arbitraire si je me rappelle correctement.

Selon Bloch (il utilise 17 comme valeur initiale et 37 en tant que multiplicateur constant):

Une valeur initiale non zéro est utilisée (...) de sorte que la valeur de hachage sera affectée par champs initiaux dont la valeur de hachage (...) est zéro. Si zéro a été utilisé comme la valeur initiale (...) La valeur de hachage globale ne serait pas affectée par de tels champs initiaux, qui pourraient augmenter les collisions. La valeur 17 est arbitraire.
...
Le multiplicateur 37 a été choisi parce qu'il est un peu étrange. Si c'était même et la multiplication débordée, les informations seraient perdues car la multiplication par deux équivalent à changer. Les avantages de l'utilisation d'un nombre premier sont moins clair, mais il est traditionnel d'utiliser des nombres premiers à cet effet.


2 commentaires

CW depuis que je viens de citer sans vergogne bloch.


Dans la deuxième édition de Java efficace, Josh Bloch utilise 31 plutôt que 37. Il explique ce choix: "Une belle propriété de 31 est que la multiplication peut être remplacée par un décalage et une soustraction pour de meilleures performances: 31 * i == (i << 5) - i . VM modernes effectue ce type d'optimisation automatiquement. "



2
votes

Utilisez hachcodebuilder des Commons Lang: XXX

Voir l'API pour façons de le faire sans utiliser de réflexion. Vous pouvez le dire quels champs à inclure ou à ignorer.

Voir aussi EqualsBuilder, pour remplacer une méthode des égaux.


0 commentaires

6
votes

Une bonne option est GUAVA 'S objets.hascode code> méthode. Il prend tout nombre d'arguments et crée un hashcode basé sur eux:

@Override public int hashCode() {
  return Objects.hashCode(a, b, c);
}


0 commentaires

0
votes

Fondamentalement, votre code de hachage doit être constitué du paramètre clé de votre pojo. Un exemple est ci-dessous.

public int hashCode() {
    int hash = 0;
    if (getRollId() != null) {
        hash += getRollId().hashCode();
    }
    if (getName() != null) {
        hash += getName().hashCode();
    }
    return hash == 0 ? System.identityHashCode(this) : hash;
}


0 commentaires

1
votes

Générez-le à l'aide de votre IDE.


0 commentaires

0
votes

Je crois que ce qui suit est une bonne pratique pour les scénarios simples: Si votre classe contient des membres réadonnants, ils constitueraient de bons candidats pour générer le hashcode de l'objet. Si votre classe ne contient cependant que les éléments de mutation, vous pouvez créer un champ Int à réadonner qui obtient la valeur basée sur les valeurs non nulles transmises au constructeur.


0 commentaires