Iterating Java Map Entries

Iterating Java Map Entries

The majority of the time when you’re working with Maps in Java, you’ll be accessing the map values via the key. There are times you need to walk the map like a list. There’s a number of ways to do this in Java, which have grown over time as the language has evolved.

Let’s take a closer look at walking over Map entries in Java using JUnit. For the series of examples below, I’m going to prepare a map for each test like this:

1

2

3

4

5

6

7

8

9

10

11

Map<Integer,String>map;

@Before

publicvoidsetup(){

map=newHashMap<>();

map.put(1,"Java");

map.put(2,"Groovy");

map.put(3,"Scala");

map.put(4,"Clojure");

map.put(5,"jRuby");

}

This is a simple HashMap in Java. I’m using generics to say the Map key is an integer, and the Map value is a String. For this example, I’m creating a map with some of the various JVM languages.

Using an Iterator over Map Entries

If you’re still stuck using Java 1.4, you might use an Iterator to walk the Map entries. But hopefully, you’re not still on Java 1.4! But there is plenty of legacy code out there still doing this.

Here is an example of using an Iterator over a map. I’m tossing in the use of Generics, so this code snippet is not Java 1.4 compliant. I’m also using the older style while loop.

I cringe a little every time I need to do a hard cast like this. It’s generally a code smell.

Using For Each over Map Entries

Java 1.5 gave us for each loops. A much nicer syntax for doing loop operations. Here is an example of using a for each loop over Map entries.

1

2

3

4

5

6

7

8

9

10

@Test

publicvoidtestMapIteration(){

List<String>jvmLangs=newArrayList<>();

for(Map.Entry<Integer,String>entry:map.entrySet()){

jvmLangs.add(entry.getValue());

}

assertjvmLangs.size()==5;

}

You can see the code is a little cleaner now. Also gone now is the cast, so this code smells better!

Using Java 8’s forEach over Map Entries

While the Java 7 release was rather boring for developers, Java 8 has brought us some really nice features to work with. We have a new forEach statement we can use in conjunction with lambdas. Here is an example of using Java 8 lambdas to iterate over Map entries.

1

2

3

4

5

6

7

8

@Test

publicvoidtestMapIteration(){

List<String>langs=newArrayList<>();

map.forEach((k,v)->langs.add(v));

assertlangs.size()==5;

}

You can see Java 8 really allows us to clean up the code. No casts here. You can also see we’re skipping over explicitly dealing with the Map.Entry object in the lambda. Even though we’re taking a shortcut here, we still have the type safety of Java.

Conclusion

I given you 3 different ways of walking over a list of map entries in Java. In my examples here you can see how the code has become cleaner as the Java programming language has evolved over the years.