Comment hashCode() et identityHashCode () fonctionnent à la fin?

comment Object.hashCode() et System.identityHashCode() travailler à l'arrière? identityHashCode() renvoie-t-il la référence de l'objet? Est-ce que hashCode() dépend de la ? de l'objet ? = = opérateur comment travailler à l'arrière.

Quelle est la différence entre hashCode() et identityHashCode() ?

33
demandé sur elect 2011-02-08 11:00:57

5 réponses

Comment faire de l'Objet.hashCode () et système.identityHashCode () travailler à l'arrière?

en supposant qu'il n'a pas été dépassé, la méthode Object.hashCode() appelle simplement System.identityHashCode(this) .

le comportement exact de System.identityHashCode(Object) dépend de la mise en œuvre de la JVM. (La mise en œuvre effective des récentes JVM Hotspot est assez intelligente, mais je m'en écarte.)

Ne identityHashCode() retour à la référence de l'objet?

Pas de. Il renvoie un int , et un int ne peut contenir de référence. (Duh!)

cet entier retourné par identityHashCode peut être lié à l'adresse (a) de la machine pour l'objet, ou il ne peut pas être 1 . La valeur retournée par identityHashCode() est garantie de ne pas changer pour la durée de vie de l'objet. Cela signifie que le GC déplace un objet (après un appel identityHashCode() ) alors il ne peut pas utiliser la nouvelle adresse de l'objet comme hashcode d'identité.

est-ce que le hashCode() dépend du ? de l'opérateur ? == comment travailler à l'arrière.

ça n'a pas de sens. Il n'y a pas d'opérateur ? == ou ?== en Java.

Quelle est la différence entre hashCode() et identityHashCode ()?

Ceci est partiellement expliqué ci-dessus. Autres différences:

  • la méthode hashcode() est une méthode en instance non finale et doit être remplacée dans toute classe où la méthode equals(Object) est remplacée. En revanche, identityHashCode(Object) est une méthode static et ne peut donc pas être dépassée.

  • la méthode identityHashCode(Object) donne vous un identificateur d'un objet qui peut (en théorie) être utilisé pour d'autres choses que de hachage et les tables de hachage. (Malheureusement, il ne s'agit pas d'un unique identifier, mais il est garanti de ne jamais changer pour la durée de vie de l'objet.)


1 - pour les JVM de génération courante, il n'est pas du tout lié à l'adresse mémoire. Voir la réponse de @bestss.

22
répondu Stephen C 2016-11-03 06:09:37

identityHashCode () fonctionne comme cela ( et à partir de maintenant il n'a rien à faire à w/ l'adresse, esp. puisque les adresses sont 64bits long, ok alignées, et 61 )

vérifie s'il y a déjà généré un, si oui renvoie le. Vous pouvez supposer qu'il y a une place dans l'en-tête de l'objet pour ce int ;

sinon: génère un nombre aléatoire ( IIRC twister Marsaglia shift-xor algorithme), chaque fil natif a sa propre graine, donc aucune information partagée. CAS le champ identityHashCode dans l'en-tête de l'objet pour mettre à jour le numéro nouvellement généré. Si CAS success renvoie la valeur, sinon - le champ contient déjà un identityHashCode généré .

vous pouvez voir le reste des réponses au sujet de la suppression du hashcode.

: si le javadoc indique toujours quelque chose à propos des adresses et du identityHashCode, quelqu'un doit mettre à jour il.

18
répondu bestsss 2017-08-28 14:47:24

C'est assez spécifique à la mise en œuvre. La seule garantie que vous obtenez est

dans la mesure du possible, la méthode hashCode définie par la classe Object renvoie des entiers distincts pour des objets distincts. (Ceci est typiquement implémenté en convertissant l'adresse interne de l'objet en un entier, mais cette technique d'implémentation n'est pas requise par le langage de programmation Java TM .)

(du Java 1.6 JavaDoc)

en théorie, cela signifie que les valeurs pourraient être déterminées arbitrairement et pourraient même être nulles pour chaque objet. Dans la pratique, c'est probablement un dérivé de l'adresse de l'objet. Bien sûr, vous devez être prudent à ce sujet. La JVM peut déplacer des objets si elle pense que c'est une bonne idée pendant une collecte des ordures, donc ce ne sera pas "juste" l'adresse mémoire. Il pourrait être tiré d'un mondial compteur, ou un hachage de l'emplacement de l'objet original, ou à partir d'un générateur de nombres aléatoires, etc.

11
répondu templatetypedef 2011-02-08 09:00:44

identityHashCode

public static int identityHashCode (Object x)

retourne le même code de hachage pour l'objet donné que celui qui serait retourné par la méthode par défaut hashCode () , que la classe de l'objet donné l'emporte ou non sur hashCode(). Le code de hachage pour la référence nulle est zéro.

voir [ Java docs ]

donc si quelqu'un a dépassé hashCode() méthode dans sa classe mais veulent toujours la valeur par défaut hashCode() qui aurait été retourné par objet hashCode() puis utiliser System.identityHashCode()

So, hashCode() appels internes System.identityHashCode() aussi longtemps que vous ne l'emportez pas dans votre classe, si vous outrepassez hashCode() il appellera votre implémentation.

2
répondu Vishrant 2017-03-30 05:57:20

beaucoup de réponses données ci-dessus, juste besoin d'ajouter quelques points.

Quand nous disons obj.hashCode() le contenu de l'obj est considéré comme, d'autre part dans System.identityHashCode(obj) le contenu n'est pas pris en considération, donc identityHashCode pour deux String , int (avec la même valeur) sera le différent mais Hashcode sera le même.

dans le cas de String pour obtenir identityHashCode string pool joue un rôle important, exemple

    Object s1 = "abcd";
    Object s2 = new String("abcd");
    Object s3 = "abcd";
    System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
    System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
    System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());

    //output:
    identityHashCode : 2018699554 HashCode : 2987074
    identityHashCode : 1311053135 HashCode : 2987074
    identityHashCode : 2018699554 HashCode : 2987074

ici s1 et s3 pointant le même ref donc identityHashCode pour s1 and s3 est toujours le même et s2 sera différent.

même pour int aussi, IntegerCache joue le rôle important pour obtenir le identityHashCode

    Object s1 = 5;
    Object s2 = new Integer(5);
    Object s3 = 5;
    System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
    System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
    System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());

    //Output
    identityHashCode : 2018699554 HashCode : 5
    identityHashCode : 1311053135 HashCode : 5
    identityHashCode : 2018699554 HashCode : 5
0
répondu Hitesh Ghuge 2018-09-15 14:35:20