2010-12-08 52 views
3

J'ai un HashMap<String,String> (appelé p2p) et je veux faire une boucle sur ses éléments. J'ai trouvé la façon simple suivante pour le faire:Dois-je utiliser un itérateur pour faire une boucle sur HashMap?

for (String key : p2p.keySet()) { 
    value = p2p.get(key); 
} 

Cependant, plus tard, j'ai découvert que les gens utilisent iterator(). Par exemple:

Iterator it = p2p.keySet().iterator(); 
while(it.hasNext()) { 
    key = it.next(); 
    value = p2p.get(key); 
} 

Pour moi, la première approche semble plus simple. Donc, ma question est pourquoi les gens utilisent la deuxième voie? A-t-il des avantages objectifs ou juste une question de goût et de subjectivité de la simplicité?

Répondre

8

Ils sont les mêmes - (. À moins que vous itérer sur un tableau, auquel cas il utilise la longueur et le réseau d'accès sous le capot), le enhanced for loop utilise un itérateur pour obtenir les éléments

Personnellement, cependant, je ne serais pas itérer tout à fait de cette façon - j'itérer sur les paires clé/valeur:

for (Map.Entry<String, String> entry : p2p.entrySet()) { 
    String key = entry.getKey(); 
    String value = entry.getValue(); 
} 

de cette façon, vous ne devez faire aucun look-ups réels.

1

Go pour entrySet si vous voulez la clé et élément:

Voici un exemple de base:

HashMap<String, Person> hm = new HashMap<String, Person>(); 

hm.put("A", new Person("p1")); 
hm.put("B", new Person("p2")); 
hm.put("C", new Person("p3")); 
hm.put("D", new Person("p4")); 
hm.put("E", new Person("p5")); 

Set<Map.Entry<String, Person>> set = hm.entrySet(); 

for (Map.Entry<String, Person> me : set) { 
    System.out.println("Key :"+me.getKey() +" Name : "+ me.getValue().getName()+"Age :"+me.getValue().getAge()); 

} 
0

Il y a deux raisons pour lesquelles je peux penser, pourquoi on peut utiliser le second (itérateur explicite) way:

  1. La "boucle foreach" a seulement été introduite avec Java 5, donc le code écrit pour les anciennes JVM ne le peut pas.
  2. Une boucle foreach fonctionne uniquement avec des idiomes simples (bien que communs) où vous traitez exactement un élément à la fois. En particulier, il ne vous laisse pas interroger la méthode hasNext() d'un itérateur qui est souvent utile, ou faire quelque chose où vous prenez des paires de valeurs et les zip dans une carte, etc.

encore, pour vos besoins vous avez raison, un itérateur explicite n'offre aucun avantage.

0

La première façon n'était pas toujours possible dans le langage Java. C'est fondamentalement un raccourci pour la deuxième voie.

2

La deuxième méthode (plus ancienne) est nécessaire si vous souhaitez supprimer des éléments pendant les itérations, par ex. utilisez Iterator.remove(). Vous ne pouvez pas supprimer des éléments de la collection au cours de l'itération à l'aide de collection.remove() - cela produit ConcurrentModificationException.

La description ci-dessus concerne principalement les collections (listes, ensembles).

0

Il y a deux raisons d'utiliser la deuxième méthode:

  • L'ignorance de l'existence de l'amélioration de la boucle.
  • Il est plus puissant - avec un Iterator, vous pouvez vérifier qu'il y a plus d'éléments avec hasNext(), et vous pouvez supprimer des éléments en itérant la liste.
0

Si vous devez itérer sur des valeurs, alors faites:

for(String value: map.values(){ 
    ... 
} 

Si vous devez itérer sur des paires valeurs-clés alors ne:

for(Map.Entry<String, String> entry: map.entrySet()){ 
    ... entry.getKey(); 
    ... entry.getValue(); 
} 

Rappelez-vous que vous MUST Utilisez explicitement Iterator (au lieu de foreach) lorsque vous voulez supprimer quelque chose de la collection pendant l'itération.