web-dev-qa-db-fra.com

Comment hashCode () et identityHashCode () fonctionnent-ils en bout de ligne?

Comment Object.hashCode() et System.identityHashCode() fonctionne-t-il à l'arrière-train? identityHashCode() renvoie-t-il la référence de l'objet? hashCode() dépend-il de? de l'objet? == opérateur comment travailler en back-end.

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

36
Himanshu

Comment Object.hashCode () et System.identityHashCode () fonctionnent-ils en bout de ligne?

En supposant qu'elle n'ait pas été remplacée, la méthode Object.hashCode() appelle simplement System.identityHashCode(this).

Le comportement exact de System.identityHashCode(Object) dépend de l'implémentation de la machine virtuelle Java. (L'implémentation réelle sur les dernières machines virtuelles Hotspot est plutôt intelligente, mais je m'éloigne du sujet.)

identityHashCode() renvoie-t-il la référence de l'objet?

Non. Il retourne une int et une int ne peut pas contenir de référence. (Duh!)

Cet entier renvoyé par identityHashCode peut être lié à l'adresse machine (a) de l'objet ou peut ne pas être1. La valeur renvoyée par identityHashCode() est garantie pour ne pas changer pendant la durée de vie de l'objet. Cela signifie que lorsque le CPG déplace un objet (après un appel identityHashCode()), il ne peut pas utiliser la nouvelle adresse de l'objet comme code de hachage d'identité.

HashCode () dépend-il du ? de l'opérateur ? == pour savoir comment travailler en back-end?.

Cela 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 en partie expliqué ci-dessus. Les autres différences incluent:

  • La méthode hashcode() est une méthode d'instance non finale et doit être remplacée dans toute classe où la fonction equals(Object) est remplacée. Par contre, identityHashCode(Object) est une méthode static et ne peut donc pas être remplacée.

  • La méthode identityHashCode(Object) vous donne un identifiant pour un objet qui peut (en théorie) être utilisé pour autre chose que des tables de hachage et des tables de hachage. (Malheureusement, ce n'est pas un unique identifiant, mais il est garanti pour ne jamais changer pendant la durée de vie de l'objet.)


1 - Pour les machines virtuelles Java de la génération actuelle, il n’a aucun lien avec l’adresse mémoire. Voir la réponse de @ bestsss.

25
Stephen C

identityHashCode () fonctionne comme ça ( et pour l’instant, il n’a rien à faire avec l'adresse, d'autant plus que les adresses ont une longueur de 64 bits, bien alignées, donc 61 )

Vérifie si le fichier est déjà généré, le cas échéant. Vous pouvez supposer qu'il y a une place dans l'en-tête de l'objet pour cette int;

sinon: génère un nombre aléatoire (twister iirc Marsaglia shift-xor algorithm), chaque thread natif a sa propre graine, donc pas d’informations partagées. CAS, le champ identityHashCode dans l'en-tête de l'objet à mettre à jour avec le nouveau numéro généré. si CAS réussit, sinon la valeur est renvoyée - le champ contient déjà une identityHashCode générée.

vous pouvez voir le reste des réponses à propos de la substitution du hashcode.

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

18
bestsss

C'est à peu près 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 généralement implémenté en convertissant l'adresse interne de l'objet en un entier, mais cette technique d'implémentation n'est pas requise par Java.TM langage de programmation.)

(À partir de Java 1.6 JavaDoc)

En théorie, cela signifie que les valeurs pourraient être déterminées de manière arbitraire et pourraient même être nulles pour chaque objet. En pratique, c'est probablement quelque chose qui découle de l'adresse de l'objet. Bien sûr, vous devez faire attention à ce sujet. La machine virtuelle Java peut déplacer des objets si elle pense que c'est une bonne idée lors d'un nettoyage de la mémoire, de sorte que l'adresse mémoire ne sera pas "juste". Il peut être extrait d'un compteur global ou d'un hachage de l'emplacement de l'objet d'origine, d'un générateur de nombres aléatoires, etc.

11
templatetypedef

identityHashCode

public static int identityHashCode (Object x)

Retourne le même code de hachage pour l'objet donné que celui qui aurait été renvoyé par la méthode par défaut hashCode (), que la classe de l'objet donné remplace ou non hashCode (). Le code de hachage pour la référence null est zéro.

Voir [ Java Docs ]

Donc, si quelqu'un a surchargé la méthode hashCode() dans sa classe mais veut toujours la valeur hashCode() par défaut qui aurait été renvoyée par ObjecthashCode(), utilisez System.identityHashCode()

Donc, hashCode() appelle en interne System.identityHashCode() tant que vous ne l'utilisez pas dans votre classe, si vous écrasez hashCode (), il appellera votre implémentation.

2
Vishrant

Beaucoup de réponses données ci-dessus, il suffit d'ajouter quelques points.

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

Dans le cas où String obtenir identityHashCode chaîne de caractères 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 la même référence, donc identityHashCode pour s1 and s3 est toujours identique et s2 sera différent.

Idem pour int également, IntegerCache joue un rôle important dans l'obtention de 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
Hitesh Ghuge