web-dev-qa-db-fra.com

L'ordre des valeurs extraites d'un HashMap est-il l'ordre d'insertion

J'essaie de comprendre l'ordre dans lequel les valeurs d'un HashMap sont/peuvent être récupérées. Voici l'extrait de code pour la même chose.

import Java.util.HashMap;

public class HashMapExample {

   public static void main(String[] args) {
       HashMap<Integer, String> hashmap = new HashMap<Integer, String>();
       hashmap.put(1, "Apple" );
       hashmap.put(2, "lemon" );
       hashmap.put(3, "orange" );
       hashmap.put(4, "banana" );
       hashmap.put(5, "litchi" );
       hashmap.put(6, "mango" );
       hashmap.put(7, "papaya" );

       System.out.println(hashmap.size());

       for (String key : hashmap.values()) {
           System.out.println(key);
       }
   }
}

sortie:

7
Apple
lemon
orange
banana
litchi
mango
papaya

Les valeurs sont imprimées dans l'ordre dans lequel elles ont été insérées. Est-ce vrai en général? Je m'attendais à ce que les valeurs soient imprimées dans un ordre arbitraire. Cela utilise Java 6.

53
javagurl

Les valeurs sont imprimées dans l'ordre dans lequel elles ont été insérées. Est-ce vrai en général? Je m'attendais à ce que les valeurs soient imprimées dans un ordre aléatoire.

L'API HashMap ne définit pas l'ordre d'itération.

Cependant, si vous regardez l'implémentation de HashMap, vous pouvez en déduire qu'il existe une relation transitoire complexe entre l'ordre d'itération, les valeurs de hachage des clés, l'ordre dans lequel les clés ont été insérées et la taille de la table de hachage. Cette relation est brouillée si la table de hachage se redimensionne.

Dans votre cas, vous utilisez les clés Integer, ce qui signifie que les valeurs de hachage des clés sont les valeurs de clé elles-mêmes. Vous avez également inséré les entrées dans l'ordre des touches. Cela conduit (fortuitement!) À l'ordre d'itération correspondant à l'ordre d'insertion. Mais si vous continuiez à insérer plus de clés, vous constateriez que l'ordre d'itération "s'enroule". Ensuite, au fur et à mesure que la table passe par une série de redimensionnements, la commande sera de plus en plus brouillée.

En bref, ce que vous voyez est un artefact de la mise en œuvre de la table de hachage, et non quelque chose que vous pouvez (ou devriez) utiliser judicieusement. Notamment parce qu'il pourrait changer d'une version Java version à la suivante).

65
Stephen C

À partir du Javadoc: HashMap "la classe ne donne aucune garantie quant à l'ordre de la carte; en particulier, elle ne garantit pas que l'ordre restera constant dans le temps."

Si vous avez besoin d'un ordre cohérent, vous pouvez utiliser LinkedHashMap (pour l'ordre d'insertion/d'accès), ou TreeMap (pour l'ordre de comparaison). Veuillez noter que ceux-ci maintiennent l'ordre des clés, pas les valeurs.

81
notnoop

Un LinkedHashMap est ce que vous recherchez. Du doco, il diffère de HashMap en ce qu'il maintient une liste doublement liée parcourant toutes ses entrées

10
Rog

Essayez LinkedHashMap si la commande est importante ... voir à partir de JavaDoc

classe publique LinkedHashMap étend HashMap

Implémentation d'une table de hachage et d'une liste liée de l'interface Carte, avec un ordre d'itération prévisible. Cette implémentation diffère de HashMap en ce qu'elle maintient une liste doublement liée parcourant toutes ses entrées. Cette liste liée définit l'ordre d'itération, qui est normalement l'ordre dans lequel les clés ont été insérées dans la carte (ordre d'insertion). Notez que l'ordre d'insertion n'est pas affecté si une clé est réinsérée dans la carte. (Une clé k est réinsérée dans une carte m si m.put (k, v) est invoqué lorsque m.containsKey (k) retournerait vrai immédiatement avant l'invocation.)

5
MadMurf

Une collection connexe est Java.util.concurrent's ConcurrentSkipListMap . Un skiplist vous permet de parcourir les entrées dans l'ordre des clés et aussi de les regarder dans un ordre aléatoire (mais pas aussi vite qu'un HashMap).

Il y a un skiplist sympa applet de démonstration .

1
Jim Ferrans