Je suis curieux de savoir comment java génère des valeurs de hachage en utilisant la méthode hashCode() de l'API d'objet?Comment fonctionne la méthode hashCode() de java?
Répondre
Java ne génère pas hashCode(), c'est-à-dire que rien d'automatique ne se produit ici. Cependant, Object
génère un HashCode basé sur l'adresse de mémoire de l'instance de l'objet. La plupart des classes (surtout si vous allez l'utiliser dans l'API Collection
) doivent implémenter leur propre HashCode (et par contrat leur propre méthode equals).
Le hashCode()
de Object
est actuellement une méthode native et l'implémentation n'est en fait pas Java pur. Maintenant, en ce qui concerne la façon dont cela fonctionne, this answer from Tom Hawtin fait un excellent travail à l'expliquer:
Beaucoup de gens prétendent que
Object.hashCode
renvoie l'adresse de la représentation de l'objet en mémoire. Dans les implémentations modernes, les objets se déplacent réellement dans la mémoire. Au lieu de cela, une zone de l'en-tête de l'objet est utilisée pour stocker la valeur, qui peut être dérivée paresseusement de l'adresse mémoire au moment où la valeur est demandée en premier.
La réponse entière vaut la peine d'être lue.
Selon la documentation de l'API Java Platform, le calcul du hashcode est basé sur l'adresse JVM interne 32 bits de l'objet.
Il est vrai que l'objet se déplace pendant l'exécution (AFAIK la seule raison est garbage collector). Mais hashcode ne change pas.
Ainsi, lorsque vous avez un objet comme celui-ci
Person person1 = new Person();
person1.setName("Alex");
Person person2 = new Person();
person2.setName("Alex");
Person person3 = person2;
Dans ce cas person1.hashCode ne sera pas égale à person2.hashCode parce que les adresses mémoire de ces deux objets ne sont pas les mêmes.
Mais person2.hashCode sera égal à person3 car ils pointent sur le même objet. Par conséquent, si vous devez utiliser la méthode hashCode pour vos objets, vous devez l'implémenter vous-même.
Par ailleurs L'implémentation String.hashCode est différente. Il est quelque chose comme ceci: (C# syntaxe)
public int hashCode(String str)
{
int h = 0;
for (int i = 0; i < str.Length; i++)
h = (h * 31) + str[i];
return h;
}
modifier: Aucun contrôle de trop-plein est fait ici, de sorte que le hashCode peut être positif ou négatif.
Java ne génère pas hashCode
significative pour vous, il est votre travail en tant que programmeur pour générer un hashCode
utile. La valeur par défaut hashCode
est juste l'emplacement de la mémoire.
Inaccurate - le hashcode par défaut est basé sur l'emplacement de la mémoire * la première fois que la méthode est appelée * pour l'objet; voir la réponse de Pascal. –
Bon point, dûment noté. – fastcodejava
Object.hashCode() utilise le System.identityHashCode() qui est basé sur un numéro d'identification pour un objet donné.
La fonction HashCode() a plusieurs options pour créer un code de hachage. Il définit le paramètre de démarrage JVM.Fonction qui créent hashCode() écrit sur C++, et vous pouvez voir le code here
- HashCode == 0: retourne simplement des nombres aléatoires sans rapport à l'endroit où en mémoire l'objet se trouve. Pour autant que je sache, la lecture-écriture globale de la graine n'est pas optimale pour les systèmes avec beaucoup de processeurs .
- HashCode == 1: Compte les valeurs de code de hachage, pas sûr à quelle valeur ils commencent, mais il semble assez élevé.
- HashCode == 2: Renvoie toujours exactement le même code de hachage d'identité de 1. Ceci peut être utilisé pour tester le code qui repose sur l'identité de l'objet. Le raison pourquoi JavaChampionTest a retourné l'URL de Kirk dans l'exemple ci-dessus est que tous les objets retournaient le même code de hachage.
- HashCode == 3: Compte les valeurs du code de hachage à partir de zéro. Il ne semble pas être thread-safe, de sorte que plusieurs threads peuvent générer des objets avec le même code de hachage.
- HashCode == 4: Cela semble avoir une certaine relation avec l'emplacement de mémoire à laquelle l'objet a été créé.
- HashCode> = 5: Il s'agit de l'algorithme par défaut pour Java 8 et comporte une graine par thread. Il utilise le schéma xor-shift de Marsaglia pour produire des nombres pseudo-aléatoires de .
L'information a été tirée de here
Comment est-ce une réponse à la question du PO? Cela aurait pu être un commentaire. – Mike
Pourquoi mon enregistrement n'a-t-il pas répondu? –
C'est une bien meilleure réponse à la question avec l'édition que vous avez ajoutée. Dommage que l'OP choisisse toujours un chemin différent. – Mike
A partir du fichier Object.java '(Ceci est généralement ** ** mis en œuvre en convertissant l'adresse ** interne ** de l'objet dans un entier, mais cette mise en œuvre la technique n'est pas ** requise par le langage de programmation Java TM.) '- Soulignez le mien. –
Est-ce que ce hashCode renvoie une valeur différente après que l'objet a été déplacé lorsque le GC se produit? – Jacky
L'idée que hashCode utilise l'adresse mémoire est un artefact historique http://stackoverflow.com/questions/36236615/does-object-tostring-or-object-hashcode-ever-give-the-memory-address-of-the -obje – Raedwald