Comment Java HashMap stocke-t-il les entrées en interne


Disons que vous avez une classe key (KeyClass) avec des méthodes equals, hashCode et clone remplacées. Supposons qu'il a 2 champs primitifs, une chaîne (nom) et un int (id).

Maintenant, vous définissez

KeyClass keyOriginal, keyCopy, keyClone;

keyOriginal = new KeyClass("original", 1);
keyCopy = new KeyClass("original", 1);
keyClone = KeyClass.clone();

Maintenant

keyOriginal.hashCode() == keyCopy.hashCode() == keyClone.hashCode()
keyOriginal.equals(keyCopy) == true
keyCopy.equals(keyClone) == true

Donc, en ce qui concerne une HashMap, keyOriginal, keyCopy et keyClone sont indiscernables.

Maintenant, si vous mettez une entrée dans le HashMap en utilisant keyOriginal, vous pouvez la récupérer en utilisant keyCopy ou keyClone, c'est-à-dire

map.put(keyOriginal, valueOriginal);
map.get(keyCopy) will return valueOriginal
map.get(keyClone) will return valueOriginal

De plus, si vous mutez la clé après l'avoir placée dans la carte, vous ne pouvez pas récupérer la valeur d'origine. Donc pour eg

keyOriginal.name = "mutated";
keyOriginal.id = 1000;

Now map.get(keyOriginal) will return null

Donc ma question est

Quand vous dites carte.keySet (), il renverra toutes les clés de la carte. Comment la classe HashMap sait-elle quelle est la liste complète des clés, valeurs et entrées stockées dans la carte?

MODIFIER Donc, si je comprends bien, je pense que cela fonctionne en faisant de la clé d'entrée une variable finale.

static class Entry<K,V> implements Map.Entry<K,V> { 
  final K key; 

(docjar.com/html/api/java/util/HashMap.java.html). Donc, même si je mute la clé après l'avoir mise dans la carte, la clé d'origine est conservée. Est ma compréhension correcte? Mais même si la référence de clé d'origine est conservée, on peut toujours muter son contenu. Donc, si le contenu est muté et que le K, V est toujours stocké à l'emplacement d'origine,comment fonctionne la récupération?

MODIFIER la récupération échouera si vous mutez la clé après avoir mis dans le hashmap. Par conséquent, il il n'est pas recommandé d'avoir des clés hashmap mutables.

Author: Basanth Roy, 2012-03-07

3 answers

HashMap maintient une table d'entrées, avec des références aux clés et valeurs associées, organisées en fonction de leur code de hachage. Si vous mutez une clé, le code de hachage changera, mais l'entrée dans HashMap est toujours placée dans la table de hachage selon le code de hachage d'origine. C'est pourquoi map.get(keyOriginal) retournera null.

map.keySet() itère simplement sur la table de hachage, renvoyant la clé de chaque entrée qu'elle possède.

 8
Author: Louis Wasserman, 2012-03-07 14:14:38

Si vous modifiez l'entrée mais pas le hashCode, vous êtes en sécurité. Pour cette raison, il est considéré comme la meilleure pratique de rendre tous les champs du hashCode, equals et compareTo, à la fois final et immuables.

 1
Author: Peter Lawrey, 2012-03-07 14:39:40

En termes simples, le HashMap est un objet dans la mémoire de votre ordinateur qui contient des clés et des valeurs. Chaque clé est unique (lisez à propos de hashcode), et chaque clé pointe vers une seule valeur.

Dans votre exemple de code, la valeur sortant de votre carte dans chaque cas est la même car la clé est la même. Lorsque vous avez modifié votre clé, il n'y a aucun moyen d'obtenir une valeur car vous n'avez jamais ajouté d'élément à votre HashMap avec la clé mutée.

Si vous avez ajouté la ligne:

map.put("mutated", 2);

Avant en mutant la clé, vous n'obtiendrez plus de valeur nulle.

 1
Author: shott85, 2012-03-07 14:42:00