web-dev-qa-db-fra.com

Pourquoi la fonction toString d'un HashMap s'imprime-t-elle avec un ordre différent?

J'ai ce morceau de code très simple et j'essayais simplement de jouer un peu avec différents types d'objets dans une carte.

//There's a bit of spanish, sorry about that
//just think 'persona1' as an object with
//a string and an int
Map mapa = new HashMap();
mapa.put('c', 12850);
mapa.put(38.6, 386540);
mapa.put("Andrés", 238761);
mapa.put(14, "Valor de 14");
mapa.put("p1", persona1);
mapa.put("Andrea", 34500);

System.out.println(mapa.toString());

Et puis j'attends de la console quelque chose comme:

{c=12850, 38.6=386540, Andrés=238761, 14=Valor de 14, p1={nombre: Andres Perea, edad: 10}, Andrea=34500}

Mais, surprise, j'ai les mêmes données dans un ordre différent:

{38.6=386540, Andrés=238761, c=12850, p1={nombre: Andres Perea, edad: 10}, Andrea=34500, 14=Valor de 14}

Peu importe si j'essaie d'autres types d'objets, même juste des chaînes ou des types numériques, cela fait toujours la même chose, cela crée un ordre différent sans apparemment aucun sens.

Quelqu'un peut-il me donner un indice pourquoi cela se produit? Ou peut-être quelque chose de trop évident me manque-t-il?

J'utilise Java 1.7 et Eclipse Juno.

10
unmultimedio

Selon la documentation d'Oracle 

La classe HashMap est à peu près équivalente à Hashtable, sauf qu'elle est non synchronisée et autorise les valeurs NULL. Cette classe ne donne aucune garantie quant à l'ordre de la carte; en particulier, cela ne garantit pas que l'ordre restera constant dans le temps.

Reportez-vous à HashMap JavaDocs.

16
Vimal Bera

Il y a 3 classes qui implémentent l'interface de carte en Java . 1. hashMap: Id ne garantit aucune commande . 2. Linked HashMap: il les stockera dans l'ordre d'insertion . 3. TreeMap: Il va stocker dans l'ordre croissant. (Valeur ASCII)

Donc, selon vos besoins, vous pouvez utiliser Linked HashMap au lieu de HashMap.so au lieu d’écrire 

Map mapa = new HashMap();

créer un objet de Linked HashMap

Map mapa = new LinkedHashMap();

suivez le lien ci-dessous pour plus d'informations.

http://docs.Oracle.com/javase/tutorial/collections/interfaces/map.html

15
Anuj Kumar Jha

HashMap pas garanti l'ordre de l'élément. Si vous souhaitez conserver l'ordre, utilisez LinkedHashMap

Voir le cas suivant

    Map<Integer,String> unOrderedMap=new HashMap<>();
    unOrderedMap.put(1,"a");
    unOrderedMap.put(3,"a");
    unOrderedMap.put(2,"a");
    System.out.println("HashMap output: "+unOrderedMap.toString());

    Map<Integer,String> orderedMap=new LinkedHashMap<>();
    orderedMap.put(1,"a");
    orderedMap.put(3,"a");
    orderedMap.put(2,"a");
    System.out.println("LinkedHashMap output: "+orderedMap.toString());

Sortie: 

   HashMap output: {1=a, 2=a, 3=a}
   LinkedHashMap output: {1=a, 3=a, 2=a}
3

Maps ne conserve pas l'ordre dans lequel les éléments ont été ajoutés, List conservera l'ordre des éléments.

"L'ordre d'une carte est défini comme l'ordre dans lequel les itérateurs des vues de collection de la carte retournent leurs éléments. Certaines implémentations de la carte, telles que la classe TreeMap, offrent des garanties spécifiques quant à leur ordre; d'autres, comme la classe HashMap, ne le sont pas. . "

1
upog

Voici comment fonctionne un hashmap: (citant d'une autre source)


Il utilise un certain nombre de "compartiments" pour stocker les paires clé-valeur. Chaque compartiment a un numéro unique - c'est ce qui l'identifie. Lorsque vous insérez une paire clé-valeur dans la carte, la table de hachage examinera le code de hachage de la clé et stockera la paire dans le compartiment dont l'identificateur est le code de hachage de la clé. Par exemple: Le code de hachage de la clé est 235 -> la paire est stockée dans le numéro de compartiment 235. (Notez qu'un compartiment peut stocker plus d'une paire clé-valeur).

Lorsque vous recherchez une valeur dans la table de hachage, en lui attribuant une clé, elle examinera d'abord le code de hachage de la clé que vous avez donnée. La table de hachage examinera ensuite le compartiment correspondant, puis comparera la clé que vous avez donnée avec les clés de toutes les paires du compartiment, en les comparant avec equals ().

Vous pouvez maintenant voir à quel point cela est très efficace pour rechercher des paires clé-valeur dans une carte: grâce au code de hachage de la clé, la table de hachage sait immédiatement dans quel compartiment il doit regarder, de sorte qu'il ne doit se confronter qu'à ce qu'il contient.

En regardant le mécanisme ci-dessus, vous pouvez également voir quelles exigences sont nécessaires sur les méthodes de touches hashCode() et equals():

  • Si deux clés sont identiques (equals () renvoie true lorsque vous les comparez), leur méthode hashCode () doit renvoyer le même nombre. Si les clés ne respectent pas cette règle, les clés égales peuvent être stockées dans des compartiments différents et la table de hachage ne pourra pas trouver de paires clé-valeur (car elles vont rechercher dans le même compartiment).

  • Si deux clés sont différentes, peu importe si leur code de hachage est identique ou non. Ils seront stockés dans le même compartiment si leurs codes de hachage sont identiques, et dans ce cas, la table de hachage utilisera equals () pour les différencier.


Maintenant, lorsque vous placez toutes vos paires "clé-valeur" dans la table de hachage et que vous les imprimez, elles sont imprimées dans un ordre aléatoire des clés qui ont été générées en hachant la valeur vous fournie pour les clés.

Si votre exigence est still pour maintenir l'ordre, vous pouvez utiliser la variable LinkedHashMap en Java.

J'espère que cela t'aides :-)

Edit: Original Post: Comment un objet Java HashMap gère-t-il différents objets avec le même code de hachage?

0
VictorCreator