In this post, we will learn different ways to iterate a Map in Java. Some of its common ways and how to use those with the help of examples. Before getting started, we assume you understand interfaces and maps in Java. However, here’s a quick recap for you.

What is a Map in Java?

There are many interpretations of this, but let’s simply put it this way.
“Map is an interface in Java, that is used to store data in the form of key-value pairs.”
If you are thinking about what are maps used for? Or when are they needed? Then there are many situations in real life when we need to store data in key-value pairs. For example, all the words corresponding to a single letter in a dictionary can be stored in the form of a map in Java.
K Kite, King, Korea, Knight,..., etc.
L Lava, Life, Light, Love, Lebanon,..., etc.
Moreover, you can have a look at the following examples to understand this better.
Key Value
Family ID Family Members
Class Name Student IDs
Area Name Zip Codes
Area Block House Numbers

Why do we need to iterate through a Map?

We need to traverse or iterate over a map for accessing, modifying or removing data. Let’s explore some of the options we have.

What are some common ways to iterate a Map in Java?

Though there are many ways to traverse a map. However, we will focus on the most efficient and simple ways.
  1. The ForEach Loop method
  2. The Iterators method
Please find the implementation of both methods below.

Using the Foreach Loop method

Example


import java.util.Map;
import java.util.HashMap;

public class ForEachDemo {

	public static void main(String[] args) {

		Map<String, String> businessDays = new HashMap<String, String>();

		// store business days i-e; key/value pairs in the Map
		businessDays.put("1", "Monday");
		businessDays.put("2", "Tuesday");
		businessDays.put("3", "Wednesday");
		businessDays.put("4", "Thursday");
		businessDays.put("5", "Friday");

		// Iterating over the Map.entrySet() using map.forEach
		for (Map.Entry<String, String> entry : businessDays.entrySet()) 
		{
			System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue()); 
		}
	}
}

Output

key = 1, value = Monday key = 2, value = Tuesday key = 3, value = Wednesday key = 4, value = Thursday key = 5, value = Friday

Explanation

In this example we used the foreach loop to iterate over the map. By using the for-each loop, we get an entrySet() which provides an automated “view” of the data in the map, in the form of key-value pairs. Each entrySet contains a key and corresponding values. Where you can use all the methods of Map.Entry<key, value> as per your requirements. Here, we have only used getKey() and getValue() to display the data on the console. As an exercise, you can explore the rest of the methods to strengthen your command on this concept.

Using the Iterators method

Example


import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class MapIterator {

	public static void main(String[] args) {

		Map<String, String> monthsInAYear = new HashMap<String, String>();

		// store business days i-e; key/value pairs in the Map
		monthsInAYear.put("1", "January");
		monthsInAYear.put("2", "February");
		monthsInAYear.put("3", "March");
		monthsInAYear.put("4", "April");
		monthsInAYear.put("5", "May");
		monthsInAYear.put("6", "June");
		monthsInAYear.put("7", "July");
		monthsInAYear.put("8", "August");
		monthsInAYear.put("9", "September");
		monthsInAYear.put("10", "October");
		monthsInAYear.put("11", "November");
		monthsInAYear.put("12", "December");

		// iterate map / traverse the map using using iterator
		Iterator<Map.Entry<String, String>> iterator = monthsInAYear.entrySet().iterator();

		while (iterator.hasNext()) 
		{
			// check if next entry exists in the map
			Map.Entry<String, String> entry = iterator.next(); 
			System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());

		}
	}
}

Output

key = 11, value = November key = 1, value = January key = 12, value = December key = 2, value = February key = 3, value = March key = 4, value = April key = 5, value = May key = 6, value = June key = 7, value = July key = 8, value = August key = 9, value = September key = 10, value = October

Explanation

In this example, we create explicit iterator to traverse / iterate over the map. First, you need to import the iterator class, and then get the iterator for the entrySet. Now traverse the map while keep checking the next entity that exists on the map. There you go! Your traversal is complete, just like that.

Is the Foreach loop better than the iterators method?

It does not matter which method you use for the traversal of a map as long as it does the job for you. In terms of performance, both for-each loop and the iterators have the same time complexity. So none is better than the other, it depends on what you need to use and when.

What is the difference between the two methods?

The for-each loop does not allow to update/modify the data in the map. On the contrary, you can easily modify data using iterators. The iterators class facilitates you by providing implementation to edit/remove the data in the map. Contrarily, if you try to edit/delete map data using the for-each loop, it will throw a ConcurrentModificationException. The reason for this is that the for-each loop implicitly creates an iterator, that is not exposed to the user. Hence, you don’t have the access to modify or delete any data.

Which traversal method to use and when?

If you are not sure whether to use the for-each or the iterators to iterate your map, then you can take the following suggestions.
  • User the iterator if you have to modify the map.
  • Use the for-each loop if you have nested loops (to avoid complexity).

Using the Stream API for Map Iteration

The Stream API, introduced in Java 8, offers a functional and concise way to iterate over a Map. This approach is particularly useful for performing operations on the Map’s entries, keys, or values in a declarative style.

Example: Iterating Over Map Entries

import java.util.HashMap;
import java.util.Map;

public class StreamMapIteration {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("Apple", 3);
        map.put("Banana", 5);
        map.put("Cherry", 2);

        map.entrySet().stream()
            .forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue()));
    }
}

This example demonstrates how to use the stream() method to process each entry in the Map with a lambda expression.

Example: Iterating Over Keys

map.keySet().stream()
    .forEach(key -> System.out.println("Key: " + key));

Example: Iterating Over Values

map.values().stream()
    .forEach(value -> System.out.println("Value: " + value));

Using parallelStream() for Map Iteration

The parallelStream() method allows you to leverage parallel processing for faster iteration, especially when dealing with large Maps. This approach splits the stream into multiple sub-streams, processing them concurrently.

Example: Parallel Processing with Map Entries

map.entrySet().parallelStream()
    .forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue()));

In this example, the parallelStream() method processes the entries concurrently, potentially reducing iteration time for large datasets.

Note: While parallelStream() can improve performance, it’s essential to consider thread-safety and whether the operation is CPU-bound to avoid unexpected behavior.

Combining Stream API Operations with Map Iteration

The Stream API enables complex operations like filtering, mapping, and collecting during Map iteration. This makes it a powerful tool for data transformation and aggregation.

Example: Filtering Map Entries

map.entrySet().stream()
    .filter(entry -> entry.getValue() > 3)
    .forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue()));

This example filters out entries where the value is greater than 3 before processing them.

Example: Transforming Map Values

map.entrySet().stream()
    .map(entry -> entry.getKey() + " has " + (entry.getValue() * 2) + " items")
    .forEach(System.out::println);

Here, the map() operation is used to transform the entries into a customized format.

Example: Collecting Results into a New Map

import java.util.stream.Collectors;

Map<String, Integer> filteredMap = map.entrySet().stream()
    .filter(entry -> entry.getValue() > 3)
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(filteredMap);

In this example, the filtered entries are collected into a new Map using Collectors.toMap().

Conclusion

By the end of the post, we hope you have learned how to iterate map in Java. You are encouraged to practise these and try out other methods of traversal as well. Feel free to hop back or post questions whenever you feel stuck. Till then, happy learning!