April 29, 2024

The ContactSunny Blog

Tech from one dev to another

Different ways of iterating on a HashMap in Java

5 min read
In this post, we will learn how to iterate over the keys in a HashMap in five different ways, including a couple of Streams APIs.
substitute for hashmap

HashMap is one of those data structures that we use a lot in our code, almost on a daily basis. And there will be situations where we’d want to iterate on the keys in a HashMap. There are many ways in which we can do it, and in this post, I’ll talk about five such ways. Before that, a disclaimer, I got the idea for this post from a LinkedIn post I saw a few days back. I don’t remember who had shared it, but I made a note of it under my blog post ideas. And that’s how we are here. And by the way, if you’re interested, learn how to implement a HashMap in Java.


The HashMap we’ll use

Before we look at the five different ways of iterating on a HashMap, let’s first have a look at the HashMap that we’re working with. Below is the code I’m using to generate the HashMap:

Map<String, String> mapForDemo = new HashMap<String, String>();
mapForDemo.put("1", "Collection Iterator");
mapForDemo.put("2", "ForEach loop with the keySet");
mapForDemo.put("3", "ForEachRemaining with Collection Iterator");
mapForDemo.put("4", "Streams on keySet");
mapForDemo.put("5", "Stream.of() on keySet");

As you can see from the code, we have String as both the key and the value. And also, I’ve just listed the five different ways as the values of the HashMap. We’ll walk through each one of them briefly in the following sections.


Iterator in the Collection framework

This is the iterator that we’ve been using forever. This iterator comes built-in in the collection framework. And the code is pretty easy to understand. So how is this done? Below is a code snippet which demonstrates the iterator:

private static void demoUsingIterator(Map<String, String> mapForDemo) {
    System.out.println("Demo of the iterator in Collection");
    System.out.println("----------------------------------");
    Iterator<String> iterator = mapForDemo.keySet().iterator();
    while(iterator.hasNext()) {
        String key = iterator.next();
        String value = mapForDemo.get(key);
        System.out.println(key + " => " + value);
    }
    System.out.println("====================================================");
}

The output of this code snippet is as follows:

Iterator in the Collection framework

ForEach loop on the keyset

When you write the code for the iterator in the collection framework, the IDE will most definitely suggest you a better code. And that better code is the forEach loop on the keySet. That’s what we’re seeing in this section.

So in this method, you basically get the keySet from the HashMap, and use the forEach loop on that. This is because Java’s forEach loop works on any Collection that uses an iterator. And this has to be one of the easiest ways to loop on HashMaps.

private static void demoUsingForEach(Map<String, String> mapForDemo) {
    System.out.println("Demo of the forEach loop");
    System.out.println("------------------------");
    for (String key : mapForDemo.keySet()) {
        String value = mapForDemo.get(key);
        System.out.println(key + " => " + value);
    }
    System.out.println("====================================================");
}

As use you can see, the number of lines of code has been reduced significantly, and the forEach loop is not that difficult of understand, it’s pretty straight forward. Anyway, the output of this code looks like this:

forEach loop on keySet

ForEachRemaining on the Collection’s Iterator

You can see this as a combination of the first two methods we discussed. That’s because we use the iterator from the Collections framework, and also use the forEach loop, at least a type of the forEach loop. Have a look at the code snippet below:

private static void demoUsingForEachRemaining(Map<String, String> mapForDemo) {
    System.out.println("Demo of the forEachRemaining loop");
    System.out.println("---------------------------------");
    Iterator<String> iterator = mapForDemo.keySet().iterator();
    iterator.forEachRemaining(key -> {
        String value = mapForDemo.get(key);
        System.out.println(key + " => " + value);
    });
    System.out.println("====================================================");
}

As you can see from the code snippet, the iterator object has the forEachRemaining() method, which is basically the forEach() method on the iterator object. The output of the code snippet above looks like this:

forEachRemaining() loop on the iterator object

ForEach method in Java Streams

When we’re talking about modern Java applications, we have to mention or use streams at least once. That has become sort of mandatory now. So, we’ll explore a couple of Streams APIs in Java which will help us iterate over a HashMap’s keys. The first is the forEach() method on a stream. The code for this is pretty straight forward. First, you convert the keySet into a stream, and then call the forEach() method on that stream. Take a look at the code below, it makes more sense:

private static void demoStreamForEach(Map<String, String> mapForDemo) {
    System.out.println("Demo of the forEach loop in Streams");
    System.out.println("-----------------------------------");
    mapForDemo.keySet().stream().forEach(key -> {
        String value = mapForDemo.get(key);
        System.out.println(key + " => " + value);
    });
    System.out.println("====================================================");
}

As you can expect, the output of this code snippet is pretty similar to the others. But I’ll put it up anyway:

forEach() loop on streams

ForEach loop on a stream of arrays

The last one on this list is using streams, arrays, and the forEach loop. In this, first we’ll get the keySet as an array. Then, we’ll pass that array to the Stream.of() method, which will create a stream of the array we passed. We’ll then call the forEach() method on this stream. It’s similar to the one we discussed earlier, but only the object we are iterating on is different. The code looks like the follows:

private static void demoStreamOfOnKeySet(Map<String, String> mapForDemo) {
    System.out.println("Demo of Stream.of() on keySet");
    System.out.println("-----------------------------");
    Stream.of(mapForDemo.keySet().toArray()).forEach(key -> {
        String value = mapForDemo.get(key);
        System.out.println(key + " => " + value);
    });
    System.out.println("====================================================");
}

Again, the output is shockingly similar to the previous ones. But you can have a look at it anyway:

forEach on stream of keyset as array

So, that’s pretty much what I have with me right now. I guess the easiest, at least for me, was the second method, where you just use the forEach method on the keySet. But, you still have other options if you want. As usual, if you like to take a look at the code for this POC, you can find it in my Github repo.


And if you like what you see here, or on my Medium blog, and would like to see more of such helpful technical posts in the future, consider supporting me on Patreon and Github.

Become a Patron!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.