web-dev-qa-db-fra.com

Itérer dans une carte de hachage

Duplicate possible:
Comment itérer efficacement sur chaque entrée d'une "carte"?

Quelle est la meilleure façon de parcourir les éléments d'un HashMap?

3177
burntsugar

Parcourez la entrySet() comme ceci:

public static void printMap(Map mp) {
    Iterator it = mp.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry pair = (Map.Entry)it.next();
        System.out.println(pair.getKey() + " = " + pair.getValue());
        it.remove(); // avoids a ConcurrentModificationException
    }
}

En savoir plus sur Map .

3117
karim79

Si vous ne vous intéressez qu'aux clés, vous pouvez parcourir la keySet() de la carte:

_Map<String, Object> map = ...;

for (String key : map.keySet()) {
    // ...
}
_

Si vous n'avez besoin que des valeurs, utilisez values() :

_for (Object value : map.values()) {
    // ...
}
_

Enfin, si vous voulez à la fois la clé et la valeur, utilisez entrySet() :

_for (Map.Entry<String, Object> entry : map.entrySet()) {
    String key = entry.getKey();
    Object value = entry.getValue();
    // ...
}
_

Une mise en garde: si vous souhaitez supprimer des éléments à mi-itération, vous devrez le faire via un itérateur (voir réponse de karim79 ). Toutefois, la modification des valeurs d’élément est OK (voir Map.Entry ).

4522
harto

Extrait de la référence Comment itérer sur une carte en Java:

Il existe plusieurs façons de parcourir un Map en Java. Passons en revue les méthodes les plus courantes et examinons leurs avantages et leurs inconvénients. Etant donné que toutes les cartes de Java implémentent l'interface Map, les techniques suivantes fonctionneront pour toute implémentation de carte (HashMap, TreeMap, LinkedHashMap, Hashtable, etc.)

Méthode n ° 1 : Itération sur des entrées à l'aide d'une boucle For-Each.

Ceci est la méthode la plus courante et est préférable dans la plupart des cas. Il doit être utilisé si vous avez besoin à la fois de clés de carte et de valeurs dans la boucle.

Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
    System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}

Notez que la boucle For-Each a été introduite dans Java 5. Cette méthode ne fonctionne donc que dans les versions les plus récentes du langage. De plus, une boucle For-Each lancera NullPointerException si vous essayez de parcourir une carte qui est null. Par conséquent, avant d'effectuer une itération, vous devez toujours vérifier les références null.

Méthode n ° 2 : itération sur des clés ou des valeurs à l'aide d'une boucle For-Each.

Si vous n'avez besoin que de clés ou de valeurs de la carte, vous pouvez effectuer une itération sur KeySet ou sur des valeurs plutôt que sur entrySet.

Map<Integer, Integer> map = new HashMap<Integer, Integer>();

// Iterating over keys only
for (Integer key : map.keySet()) {
    System.out.println("Key = " + key);
}

// Iterating over values only
for (Integer value : map.values()) {
    System.out.println("Value = " + value);
}

Cette méthode offre un léger avantage en termes de performances par rapport à l'itération entrySet (environ 10% plus rapide) et est plus propre.

Méthode n ° 3 : Itération à l'aide d'Iterator.

Utilisation de génériques:

Map<Integer, Integer> map = new HashMap<Integer, Integer>();
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
    Map.Entry<Integer, Integer> entry = entries.next();
    System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}

Sans génériques:

Map map = new HashMap();
Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) {
    Map.Entry entry = (Map.Entry) entries.next();
    Integer key = (Integer)entry.getKey();
    Integer value = (Integer)entry.getValue();
    System.out.println("Key = " + key + ", Value = " + value);
}

Vous pouvez également utiliser la même technique pour parcourir keySet ou des valeurs.

Cette méthode peut sembler redondante, mais elle a ses propres avantages. Tout d’abord, c’est le seul moyen de parcourir une carte dans les anciennes versions de Java. L'autre caractéristique importante est qu'il s'agit de la seule méthode permettant de supprimer des entrées de la carte lors de l'itération en appelant iterator.remove(). Si vous essayez de faire cela pendant l'itération For-Each, vous obtiendrez des "résultats imprévisibles" selon Javadoc .

Du point de vue des performances, cette méthode est égale à une itération For-Each.

Méthode n ° 4 : itération sur des clés et recherche de valeurs (inefficace).

Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Integer key : map.keySet()) {
    Integer value = map.get(key);
    System.out.println("Key = " + key + ", Value = " + value);
}

Cela peut sembler une alternative plus propre pour la méthode n ° 1, mais en pratique, il est assez lent et inefficace, car obtenir des valeurs par une clé peut prendre beaucoup de temps (cette méthode dans différentes implémentations de Map est 20 à 200% plus lente que la méthode n ° 1 ). Si FindBugs est installé, il le détectera et vous avertira d'une itération inefficace. Cette méthode devrait être évitée.

Conclusion:

Si vous n'avez besoin que de clés ou de valeurs de la carte, utilisez la méthode n ° 2. Si vous êtes coincé avec l'ancienne version de Java (moins de 5) ou prévoyez de supprimer des entrées lors de l'itération, vous devez utiliser la méthode n ° 3. Sinon, utilisez la méthode n ° 1.

810
arvind
for (Map.Entry<String, String> item : hashMap.entrySet()) {
    String key = item.getKey();
    String value = item.getValue();
}
148
gabor

Vous pouvez parcourir les entrées d'un Map de plusieurs manières. Obtenez chaque clé et valeur comme ceci:

Map<?,?> map = new HashMap<Object, Object>();
for(Entry<?, ?> e: map.entrySet()){
    System.out.println("Key " + e.getKey());
    System.out.println("Value " + e.getValue());
}

Ou vous pouvez obtenir la liste des clés avec

Collection<?> keys = map.keySet();
for(Object key: keys){
    System.out.println("Key " + key);
    System.out.println("Value " + map.get(key));
}

Si vous voulez juste obtenir toutes les valeurs et que vous n'êtes pas concerné par les clés, vous pouvez utiliser:

Collection<?> values = map.values();
93
codethulhu

Plus intelligent:

for (String key : hashMap.keySet()) {
    System.out.println("Key: " + key + ", Value: " + map.get(key));
}
64
jkarretero

Dépend. Si vous savez que vous allez avoir besoin de la clé et de la valeur de chaque entrée, passez à la entrySet. Si vous avez juste besoin des valeurs, alors il y a la méthode values(). Et si vous avez juste besoin des touches, utilisez keyset().

Une mauvaise pratique serait de parcourir toutes les clés, puis dans la boucle, faites toujours map.get(key) pour obtenir la valeur. Si vous faites cela, alors la première option que j'ai écrite est pour vous.

45
Gary Kephart