Comment pouvons-nous décider de la meilleure implémentation de la méthode de hashcode pour une collection?
Réponses
Trop de publicités?La meilleure mise en œuvre? C'est une des questions difficiles, car il dépend de la configuration d'utilisation.
Un pour presque tous les cas, bonne mise en œuvre a été proposée dans Josh Bloch "Effective Java" dans l'article 8. La meilleure chose est de regarder là-haut, car l'auteur explique pourquoi la démarche est la bonne.
Une version courte:
1) Créer un int result et d'attribuer une valeur non nulle.
2) Pour chaque testé sur le terrain dans l'est égal à-Méthode, calculer un hash code c par:
- Si le champ f est une valeur booléenne: calculer
(f ? 0 : 1)
; - Si le champ f est un byte, char, short ou int: calculer
(int)f
; - Si le champ f est une longue: calculer
(int)(f ^ (f >>> 32))
; - Si le champ f est un float: calculer
Float.floatToIntBits(f)
; - Si le champ f est double: calculer
Double.doubleToLongBits(f)
et de traiter la valeur de retour comme chaque valeur de type long; - Si le champ f est un objet: Utiliser le résultat de la
hashCode()
méthode ou 0 sif == null
; - Si le champ f est un tableau: Voir chaque champ de l'élément séparé et calculer la valeur de hachage dans un appel récursif à la mode et de combiner les valeurs comme décrit par la suite.
3) Combiner la valeur de hachage c, avec un résultat avec:
result = 37 * result + c
4) résultat de Retour
Cela devrait se traduire par une distribution correcte des valeurs de hachage pour la plupart des situations d'utilisation.
Si vous êtes satisfait de l’implémentation Effective Java recommandée par dmeister, vous pouvez utiliser un appel de bibliothèque au lieu de lancer votre propre appel:
@Override
public int hashCode(){
return Objects.hashCode(this.firstName, this.lastName);
}
Cela nécessite soit goyave ( com.google.common.base.Objects.hashCode(...)
) ou JDK7 ( java.util.Objects.hash(...)
) mais fonctionne de la même manière.
Assurez-vous d'abord que est égal à est correctement mis en œuvre. À partir d' un IBM DeveloperWorks article:
- Symétrie: Pour les deux références, a et b, une.equals(b) si et seulement si b.est égal à(a)
- La réflexivité: Pour tous les non-null références, une.est égal à(a)
- Transitivité: Si un.equals(b) et b.est égal à(c), puis un.est égal à(c)
Assurez-vous que leur relation avec hashCode respecte le contact (à partir du même article):
- La cohérence avec hashCode(): Deux objets égaux doivent avoir le même hashCode() de la valeur
Enfin une bonne fonction de hachage doit s'efforcer d'approcher l' idéal de fonction de hachage.