10
votes

Java, Object.HashCode () Résultat constant sur tous les JVM / Systems?

est la sortie de objet.hashcode () requise pour être identique à toutes les implémentations JVM pour le même objet?

Par exemple, si "test" .HashCode () retourne 1 sur 1.4, pourrait-il potentiellement retourner 2 en cours d'exécution sur 1.6. Ou si si les systèmes d'exploitation étaient différents, ou une architecture de processeur différente entre les instances?


0 commentaires

6 Réponses :


6
votes

de l'API

Le contrat général de HASHCODE est:

  • Chaque fois que cela est invoqué sur le même objet plus d'une fois lors d'une exécution d'une application Java, la méthode de code HASHCODE doit renvoyer systématiquement le même entier, à condition qu'aucune information utilisée dans des comparaisons égales sur l'objet est modifiée. Cet entier n'a pas besoin de rester compatible avec une exécution d'une application à une autre exécution de la même application.
  • Si deux objets sont égaux en fonction de la méthode Equals (Object), appelez la méthode HashCode sur chacun des deux objets doit produire le même résultat entier.
  • Il n'est pas nécessaire que si deux objets soient inégaux en fonction de la méthode Equals (Java.lang.Object), appelez la méthode de code HASHCODE sur chacun des deux objets doit produire des résultats entiers distincts. Toutefois, le programmeur doit être conscient que la production de résultats entiers distincts pour des objets inégaux peut améliorer la performance des hashtables.

    Autant que c'est raisonnablement pratique, la méthode de code Hashcode définie par l'objet de classe renvoie des entiers distincts pour des objets distincts. (Ceci est typiquement mis en œuvre en convertissant l'adresse interne de l'objet en un entier, mais cette technique de mise en œuvre n'est pas requise par le langage de programmation Javatm.)


2 commentaires

@Finnw: Oui ça fait; Le hashcode n'est pas tenu de renvoyer la même valeur sur différents exécutions de la même version sur le même système pour la même application, ce qui ne vous dérange pas à travers différentes versions ou différents systèmes ou différentes applications.


Le code de hachage d'identité est typiquement stocké dans l'en-tête d'objet (hotspot)



4
votes

Non, le résultat de hashcode () est seul constante lors d'une seule exécution. Vous ne devriez pas vous attendre à ce que le résultat de la fonction soit identique entre les exécutions, encore moins entre les versions ou les plates-formes JRE.


0 commentaires

20
votes

non. La sortie de hashcode est susceptible de modifier entre les implémentations JVM et même entre différentes exécutions d'un programme sur le même JVM .

Cependant, dans l'exemple spécifique que vous avez donné, la valeur du "test" .hashcode () sera être cohérent parce que la mise en œuvre de hashcode pour chaîne fait partie de l'API de chaîne (voir Les Javadocs pour java.lang.string et cet autre alors post ).


2 commentaires

(Bien que ce soit différent si vous pouvez trouver un 1,0 JDK. La définition brisée dans l'API Docs lancerait des exceptions s'il est mis en œuvre.)


Il est également bien défini pour la plupart des collections



0
votes

Tout d'abord, le résultat de HASHCODE dépend fortement du type d'objet et de sa mise en œuvre. Chaque classe, y compris ses sous-classes, peut définir son propre comportement. Vous pouvez compter sur elle à la suite du contrat général comme indiqué dans la Javadoc ainsi que dans d'autres réponses. Mais la valeur n'est pas nécessaire pour rester identique après un redémarrage VM. surtout si cela dépend des implémentations de .Hashcode des classes de soirée au fil.

Lorsque vous vous référez à la mise en œuvre concrète de la classe de chaîne, vous ne devez pas dépendre de la valeur de retour. Si votre programme est exécuté dans une machine virtuelle différente, cela pourrait potentiellement changer.

Si vous vous référez uniquement au Sun VM, on pourrait soutenir que Sun ne cassera pas - même mal programmé - code existant. donc "test" .Hashcode () retournera toujours exactement 3556498 pour toute version du Sun VM .

Si vous voulez vous tirer de manière délibérante dans le pied, allez-y et dépendez-en de cela. Les personnes qui devront réparer votre code en cours d'exécution sur la "Nintendo Java VM 2015" pour le sèche-cheveux "2015" vont crier votre nom la nuit.


0 commentaires

0
votes

Comme indiqué, pour de nombreuses implémentations, le comportement par défaut du hashcode () est de renvoyer l'adresse de l'objet. De toute évidence, cela peut être différent chaque fois que le programme est exécuté. Ceci est également cohérent avec le comportement par défaut des égaux (): Deux objets sont égaux uniquement si elles sont identiques sur le même objet (où X et Y sont à la fois non NULL, X.Equals (Y) si et uniquement si x == Y) .

Pour toutes les classes où HashCode () et Equals () sont remplacés, ils sont généralement calculés de manière déterministe basée sur les valeurs de certains ou de tous les membres. Ainsi, dans la pratique, il est probable que si un objet dans une exécution du programme peut être dit être égal à un objet dans une autre exécution du programme, et le code source est le même (y compris des éléments tels que le code source de chaîne .HashCode () si cela est appelé par la substitution de HashCode ()), les codes de hachage seront les mêmes.

Il n'est pas garanti, bien qu'il soit difficile de penser à un exemple réel raisonnable.


2 commentaires

@Mark: Un exemple raisonnable est l'endroit où vous remplacez hashcode () et que le hashcode calc incluent le code HASHCode d'un objet composant dont le code hashcode () n'est pas remplacé.


Cela le ferait, mais vous ne seriez pas en mesure de permettre à deux objets d'être égaux. Deux objets "égaux" auraient différents hashcodes. Si vous mettez un tel objet dans un hashmap, vous ne seriez pas en mesure de le retrouver.