web-dev-qa-db-fra.com

Que se passe-t-il si deux objets différents ont le même hashcode?

Je crois comprendre que deux objets inégaux peuvent avoir le même hashcode. Comment cela serait-il géré lors de l'ajout ou de la récupération d'un fichier java HashMap?

16
Joey

Ils seront simplement ajoutés au même compartiment et equals() sera utilisé pour les distinguer. Chaque compartiment peut contenir une liste d'objets avec le même code de hachage.

En théorie, vous pouvez renvoyer le même entier qu'un code de hachage pour n'importe quel objet d'une classe donnée, mais cela signifierait que vous perdriez tous les avantages en termes de performances de la carte de hachage et, en fait, stockerait les objets dans une liste.

28
Alex Gitelman

Dans HashMap, les clés et leurs valeurs associatives sont stockées dans un nœud de liste lié dans le compartiment et les clés sont essentiellement comparées dans hashmap à l'aide de la méthode equals () et non par hashcode.

hm.put("a","aValue"); // Suppose hashcode created for key "a" is 209 
hm.put("b","bValue"); // Here hashcode created for key "b" is 209 as well.
  • Si a.equals(b) renvoie true, bValue remplacera aValue et bValue sera renvoyé.
  • Si a.equals(b) renvoie false, un autre nœud sera créé dans la liste des compartiments. Ainsi, lorsque vous appelez get("b"), vous obtiendrez bValue puisque a.equals(b) est false.
7
Yash

HashMap travaille sur le concept de hachage et d'indexation. En interne, HashMap stocke les valeurs dans Array of Nodes. Chaque nœud se comporte comme une liste liée. 

Chaque nœud de la liste liée a 4 valeurs:

  1. int hash
  2. K key
  3. V value
  4. Node<K, V> next

HashMap structure interne:

 HashMap Internal structure Image

Lors de l'insertion de la valeur dans HashMap, le premier hashcode de Key est généré et basé sur un algorithme, il calcule l'index.

Ainsi, notre valeur sera stockée dans un index spécifique avec hashcode, clé, valeur et adresse de l'élément suivant.

Lors de la récupération de la valeur depuis HashMap, le premier hashcode sera généré puis indexé (de la même manière qu'au moment de l'insertion). Tout en récupérant la valeur de index, il vérifie d’abord le hashcode; si hashcode correspond, il vérifie uniquement la clé de Node en utilisant la méthode equals. Si key correspond, alors seul valeur ou bien il recherchera le prochain nœud avec le même hashcode.

1
Gaurav Lal

Dans ce cas, vous pouvez utiliser IdentityHashMap, où différents objets avec le même hachage sont considérés comme différents en fonction de leur identité.

0
kenmar

Lorsque deux objets inégaux ont la même valeur de hachage, cela provoque une collision dans la table de hachage, car les deux objets veulent être dans le même emplacement (parfois appelé compartiment). L'algorithme de hachage doit résoudre de telles collisions. En revenant dans les mémoires de mon cours d'algorithme universitaire, je me souviens de trois façons de faire:

  1. Recherchez le prochain emplacement vide dans la table de hachage et placez-y l'objet. Avantages: facile à mettre en œuvre, inconvénients: peut conduire à la mise en cluster d'objets et à la dégradation des performances, la capacité peut être dépassée
  2. Avoir une fonction de hachage secondaire à utiliser en cas de conflit: Avantages: généralement rapide, contre: doit écrire une deuxième fonction de hachage et peut toujours avoir des collisions, et la capacité peut être dépassée
  3. Créez une liste chaînée d'objets à partir de l'emplacement en conflit de la table de hachage. Avantages/inconvénients: généralement rapide pour une fonction de hachage décente et des facteurs de charge, mais peut se dégrader en recherche linéaire dans le pire des cas

Je pense que les classes de hachage Java utilisent la troisième méthode, mais elles pourraient utiliser une approche combinée. La clé du bon hachage consiste toutefois à s’assurer que la table de hachage a une capacité suffisante et à écrire de bonnes fonctions de hachage. Une table de hachage comportant uniquement autant de compartiments que d'objets qu'elle contient aura probablement des conflits. Généralement, vous voulez que la table de hachage soit environ deux fois plus grande que le nombre d'objets qu'elle stocke. HashMap de Java augmentera au besoin, mais vous pouvez lui attribuer une capacité de départ et un facteur de charge si vous le souhaitez.

La fonction de hachage appartient au programmeur. Vous pouvez simplement renvoyer 0 pour tous les objets, mais cela signifiera que le hachage (à la fois le stockage et la récupération) deviendra O(n) au lieu de O(1) ... ou dans conditions générales, ce sera un chien lent. 

Référence: http://www.coderanch.com/t/540275/Java/java/objects-hashcode-HashMap-retrieve-objects

0
supernova