简体   繁体   中英

Should I use an iterator to make a loop over HashMap?

I have a HashMap<String,String> (called p2p ) and I want to make a loop over its elements. I found the following simple way to do it:

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

However, later I found out that people use iterator() . For example:

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

For me the first way looks simpler. So, my question is why people use the second way? Does it have some objective advantages or it is just question of taste and subjectivity of the simplicity?

They're the same - the enhanced for loop uses an iterator to get the elements (unless you're iterating over an array, in which case it uses the length and array access under the hood.)

Personally, however, I wouldn't iterate quite that way - I'd iterate over the key/value pairs:

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

That way you never need to do any actual look-ups.

The second (older) way is necessary if you want to remove elements during iterations, eg use Iterator.remove(). You cannot remove elements from collection during iteration using collection.remove() - this produce ConcurrentModificationException.

The description above mostly relevant for collections (lists, sets).

Go for EntrySet if you want both key and element :

Here is a basic example :

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());

}

There are a couple of reasons I can think, of why one might use the second (explicit iterator) way:

  1. The "foreach loop" was only introduced with Java 5, so code written for older JVMs won't can't it.
  2. A foreach loop only works with simple (albeit common) idioms where you deal with exactly one element at a time. In particular, it doesn't let you query the hasNext() method of an iterator which is often useful, or do something where you take pairs of values and zip them into a map, etc.

Still, for your purposes you're right, an explicit iterator offers no advantages.

The first way was not always possible in the Java language. It is basically a shortcut for the second way.

There are two reasons for using the second method:

  • Ignorance of the existence of the enhanced for loop.
  • It is more powerful - with an Iterator , you can check that there are more elements with hasNext() , and you can remove elements while iterating the list.

If you need to iterate over values, then do:

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

If you need to iterate over key-values pairs then do:

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

Remember that you MUST use explicit Iterator ( instead of foreach ) when you want to remove something from the collection during iteration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM