2

I have two ways we can iterate through each entry in hashmap, can you explain which one is to be preferred over other and why ?

HashMap m = new HashMap();
m.put("A",100);
m.put("B",100);
m.put("C",100);
m.put("D",100);

One way to iterate

Set s1 = m.entrySet();
Iterator itr = s1.iterate();
while(itr.hasNext()) {
Map.Entry m1 = (Map.Entry)s1.next();
System.out.println(m1.getKey()+"..."+m1.getValue);
}

Second Way to iterate

Set<Map.Entry<String,Integer>> s1 = m.entrySet();
for(Map.Entry<String,Integer> m1:s1){
System.out.println(m1.getKey()+"..."+m1.getValue); 
}
  • I prefer the second one. It gives you type safely etc. But I have no proof etc that it performs better etc. – Stefan Nov 13 '17 at 09:33
  • please correct the code of the first way so that the difference concentrate to the main aspect for example: `for (Iterator> itr = m.entrySet().iterator();itr.hasNext();) {` `Map.Entry elem = itr.next();` `System.out.println(elem.getKey() + "..." + elem.getValue());` `}` – Carlo Bellettini Nov 13 '17 at 10:33

3 Answers3

3

The two are essentially the same (except of the raw types in the first snippet - if you use explicit Iterator, there's no reason to use raw Set, Iterator and Map.Entry - use Set<Map.Entry<String,Integer>>, Iterator<Map.Entry<String,Integer>> and Map.Entry<String,Integer>).

The enhanced for loop creates an Iterator behind the scenes.

However, if you wish to remove elements from the Set while iterating over it, you must use an explicit Iterator (and that Iterator's remove() method).

In addition, in the first snippet you can combine the first two statements - Iterator<Map.Entry<String,Integer>> itr = m.entrySet().iterator(); - since you don't need the Set reference.

Eran
  • 387,369
  • 54
  • 702
  • 768
2

NOTE: for a simpler comparison of the real differences I rewrote the code

if you want just work on the elements forgetting that they belongs to a container... the second way is better because more concise and clearer to read

for (Map.Entry<String,Integer> elem : m.entrySet()) {
  System.out.println(elem.getKey() + "..." + elem.getValue()); 
}

but, if you need to operate on the container structure itself (e.g., add, delete elements)... the first way is the correct one

for (Iterator<Map.Entry<String, Integer>> itr = m.entrySet().iterator(); 
     itr.hasNext();) { 
  Map.Entry<String, Integer> elem = itr.next(); 
  System.out.println(elem.getKey() + "..." + elem.getValue());  
}
Carlo Bellettini
  • 1,130
  • 11
  • 20
1

They're equivalent, so I would definitely prefer the second, because it's simpler, and a little bit faster (although it will probably be hard to notice).

I'd simplify it even further though:

for(Map.Entry<String,Integer> m1 : s1.entrySet()){
  System.out.println(m1.getKey() + "..." + m1.getValue); 
}
Fabien Viger
  • 111
  • 4