6/12/2006

4 Ways to Traverse a Map

Usually I don't need to traverse a java.util.Map, which is meant to be looked up, not iterated through. I traverse a java.util.Map primarily for debugging purposem, to dump its content. In case you do need to, here are 4 ways I've tried, just as examples:

import static java.net.HttpURLConnection.*;
import java.util.*;

public class MapTest {
public static void main(String... args) {
traverseMap();
}

private static void traverseMap() {
Map<Integer, String> data = new HashMap<Integer, String>();
data.put(HTTP_OK, "HTTP_OK");
data.put(HTTP_FORBIDDEN, "HTTP_FORBIDDEN");
data.put(HTTP_NOT_FOUND, "HTTP_NOT_FOUND");

System.out.printf("%nUsing JDK 5 foreach and entry set:%n");
Set<Map.Entry<Integer, String>> entries = data.entrySet();
for(Map.Entry<Integer, String> entry : entries) {
Integer key = entry.getKey();
String value = entry.getValue();
System.out.printf("%s = %s%n", key, value);
}

System.out.printf("%nUsing Iterator<Map.Entry> and entry set:%n");
for(Iterator<Map.Entry<Integer, String>> it = entries.iterator(); it.hasNext();) {
Map.Entry<Integer, String> entry = it.next();
Integer key = entry.getKey();
String value = entry.getValue();
System.out.printf("%s = %s%n", key, value);
}

System.out.printf("%nUsing JDK 5 foreach and key set:%n");
for(Integer key : data.keySet()) {
String value = data.get(key);
System.out.printf("%s = %s%n", key, value);
}

System.out.printf("%nUsing traditional Iterator and key set%n");
for(Iterator<Integer> it = data.keySet().iterator(); it.hasNext();) {
Integer key = it.next();
String value = data.get(key);
System.out.printf("%s = %s%n", key, value);
}
}
}
You may have noticed I'm using primitive int numbers (200, 403, 404) as the map key. Thanks to auto-boxing in JDK 5, I can use primitive s and their wrapper types interchangeably. Another useful feature in JDK 5 used here is using static import to import all HTTP status constants from java.net.HttpURLConnection.

To compile and run the test:

$ javac MapTest.java
$ java MapTest

Using JDK 5 foreach and entry set:
200 = HTTP_OK
403 = HTTP_FORBIDDEN
404 = HTTP_NOT_FOUND

Using Iterator<Map.Entry> and entry set:
200 = HTTP_OK
403 = HTTP_FORBIDDEN
404 = HTTP_NOT_FOUND

Using JDK 5 foreach and key set:
200 = HTTP_OK
403 = HTTP_FORBIDDEN
404 = HTTP_NOT_FOUND

Using traditional Iterator and key set
200 = HTTP_OK
403 = HTTP_FORBIDDEN
404 = HTTP_NOT_FOUND
There is some discussion on entrySet vs keySet in the comment section of a previous post: Unnecessary Cast in Map. Basically, using entry set is faster than using key set in traversing a Map. I also learned to use entrySet from there.

7 comments:

Ali Hammad Baig said...

nice tutorial .. helped me alot

Anonymous said...

this does not compile (in JDK 1.7)... a few errors. If you could look into it I'd love it.

javahowto said...

Updated code sample to include the complete test class and output, to use generics collection, and to use printf instead of println for better formatting.

Matthew Doucette said...

Sorry I pasted the wrote code fix... but looks like you fixed it anyway. I meant the map.entry needed to be capitalized into Map.Entry. You can remove that bad comment from me.

I'll sign this one this time with my real name!

javahowto said...

Thanks for spotting this. I guess what happened was, I forgot to escape < and > around Map.Entry, and blogger treated them as an html element and made them all lowercase.

Anonymous said...

Awesome one !

Anna said...

Great and Useful Article.

Online Java Course

Java Online Training

Java Course Online

J2EE training

online J2EE training

Best Recommended books for Spring framework

Java Interview Questions












Java Training Institutes in Chennai

Java Training in Chennai

J2EE Training in Chennai

java j2ee training institutes in chennai