Maison > Questions et réponses > le corps du texte
PHP中文网2017-04-18 10:47:27
Convention générale d'implémentation des hashCode
méthodes
Lors de l'exécution de l'application, tant que les informations utilisées dans l'opération de comparaison de la méthode
equals
de l'objet ne sont pas modifiées, alors le même objet est appelé plusieurs fois, et la méthodehashCode
doit renvoie systématiquement le même nombre entier. Lors de plusieurs exécutions d'une même application, les entiers renvoyés par chaque exécution peuvent être incohérents.Si deux objets sont égaux selon la comparaison de la méthode
equals(Object)
, alors l'appel de la méthodehashCode
de l'un ou l'autre objet doit produire le même résultat entier . Au contraire, si la méthodehashCode
de deux objets renvoie le même résultat entier, cela ne signifie pas que les deux objets sont égaux, car la méthodeequals
peut être surchargée.Si deux objets ne sont pas égaux selon la comparaison de la méthode
equals(Object)
, alors appeler la méthodehashCode
de l'un ou l'autre objet ne produit pas nécessairement des résultats entiers différents. Cependant, si vous pouvez faire en sorte que différents objets produisent des résultats entiers différents, il est possible d'améliorer les performances de la table de hachage.
hashCode
Calcul du code de hachage (à partir de : Effective Java)
enregistre une valeur constante non nulle, telle que
17
, dans une variable de typeresult
nomméeint
.Pour chaque champ clé
f
de l'objet ( fait référence à chaque champequals
impliqué dans la méthode), complétez les étapes suivantes :
Calcule un hash code c de type
int
pour ce champ :
Évalue (
boolean
) si le champ est de typef?1:0
.Si le champ est de type
byte
,char
,short
ou int, alors(int)f
est calculé.Évalue
long
si le champ est de type(int)(f^(f>>>32))
.Évalue
float
si le champ est de typeFloat.floatToIntBits(f)
.Si le champ est de type
double
, calculezDouble.doubleToLongBits(f)
, puis suivez l'étape 2.1.3 pour calculer une valeur de hachage pour la valeur de typelong
résultante.Si le champ est une référence d'objet et que la méthode
equals
de la classe compare le champ en appelant récursivementequals
, alors elle appelle égalementhashCode
de manière récursive pour le champ. Si une comparaison plus complexe est requise, calculez une forme normale(canonical representation)
pour le champ, puis appelezhashCode
par rapport à cette forme normale. Si la valeur de ce champ estnull
, alors0
est renvoyé (d'autres constantes sont également acceptables).Si le champ est un tableau, chaque élément doit être traité comme un champ distinct. Autrement dit, appliquez les règles ci-dessus de manière récursive, calculez un code de hachage pour chaque élément significatif, puis combinez ces valeurs de hachage selon l'étape 2.2. Si chaque élément du champ du tableau est important, vous pouvez profiter de l'une des méthodes ajoutées dans la version 1.5
Arrays.hashCode
.D'après la formule suivante, fusionnez le code de hachage
c
calculé à l'étape 2.1 dansresult
:result = 31 * result + c
; //Ici31
est un nombre premier impair, et il y a un très A. une fonctionnalité intéressante, utilisant des décalages et des soustractions au lieu de multiplications, peut conduire à de meilleures performances : `31*i == (i<<5) - i.Retour
result
Vérifiez et testez que l'implémentation
hashCode
est conforme aux conventions communes.
Exemple de mise en œuvre
@Override
public int hashCode() {
int result = 17;
result = 31 * result + (origin == null ? 0 : origin.hashCode());
result = 31 * result + (hsNumber == null ? 0 : hsNumber.hashCode());
result = 31 * result + (imageUrl == null ? 0 : imageUrl.hashCode());
result = 31 * result + (classificationName == null ? 0 : classificationName.hashCode());
return result;
}
大家讲道理2017-04-18 10:47:27
L'int de Java est fixé à 32 bits. De plus, votre latitude et votre longitude sont le double... Je pense que ce sera 64 bits.
Hashcode et ses équivalents ont une sémantique convenue. Vous pouvez jeter un œil à Object
.Je pense que les égaux que vous avez écrits peuvent être utilisés.
Remarque : Le contrat dans la classe Object est en fait une contrainte très faible. Nous pouvons écrire hashcode() et equals() comme ceci sans violer le contrat ;
public int hashcode() {
return 0;
}
public boolean equals(Object o) {
return (o != null) && (o.getClass() == getClass());
}
La vraie question est donc comment définissez-vous l’égalité. Le code est secondaire.
Si l'égalité est définie comme "la longitude et la latitude sont respectivement égales", alors le code que vous avez donné est une solution utilisable (mais pas la seule solution disponible).