Different ways to iterate any Map in Java4 min read

1. Using entrySet()

The Map.entrySet() returns a collection view Set<Map.Entry<K, V>> of the mappings in this map. To iterate over a map, we can use the getKey() method to get the current key and getValue() to get the corresponding value for each entry by Map.Entry<K, V>:

Map<Integer, String> users = new HashMap<>();
users.put(1, "Nam Do");
users.put(2, "Ethan McCue");
users.put(3, "Morty Smith");

for(Map.Entry<Integer, String> user: users.entrySet()) {
     System.out.println("Key: " + user.getKey() + " -> Value: " + user.getValue());
}

Output:

Key: 1 -> Value: Nam Do
Key: 2 -> Value: Ethan McCue
Key: 3 -> Value: Morty Smith

2. Using keySet()

The Map.keySet() method returns the collection of keys contained in a map represented by a Set<K>. Once we have the keys, we can easily get the mapping values by using the get(Object key) method of the map:

Map<Integer, String> users = new HashMap<>();
users.put(1, "Nam Do");
users.put(2, "Ethan McCue");
users.put(3, "Morty Smith");

for(Integer key: users.keySet()) {
    System.out.println("Key: " + key + " -> Value: " + users.get(key));
}

3. Using the forEach() method

Since Java 8, you can use the Map.forEach() method to iterate through a map. This is the default method of the Map interface which takes a BiConsumer<? super K, ? super V>. For more specific, the BiConsumer is a functional interface which has a single method void accept(T t, U u); which takes 2 parameters and returns nothing. In our case, we provide the key as the former argument and the value for the latter one.

We can iterate through the map with forEach() by using lambda expression:

Map<Integer, String> users = new HashMap<>();
users.put(1, "Nam Do");
users.put(2, "Ethan McCue");
users.put(3, "Morty Smith");

users.forEach((key, value) -> System.out.println("Key: " + key + " -> Value: " + value));

Or you’re interested in how the forEach() works, here is the more verbose implementation of the BiConsumer interface, which is being passed as an argument of the forEach() method:

Map<Integer, String> users = new HashMap<>();
users.put(1, "Nam Do");
users.put(2, "Ethan McCue");
users.put(3, "Morty Smith");

users.forEach(new BiConsumer<Integer, String>() {
     @Override
     public void accept(Integer integer, String s) {
          System.out.println("Key: " + integer + " -> Value: " + s);
     }
});

Of course, it’s incentivized using lambda expression over this one.

4. Using stream() in Java 8

You can also use the stream() method on a entry set:

Map<Integer, String> users = new HashMap<>();
users.put(1, "Nam Do");
users.put(2, "Ethan McCue");
users.put(3, "Morty Smith");
users.entrySet().stream().forEach(entry -> System.out.println("Key: " + entry.getKey() + " -> Value: " + entry.getValue()));

Why don’t you use forEach method directly on the map like the previous one instead of doing this, you might ask. Well, this stream() method returns a Stream (which is simply just a chunk of data readily for some operations), it comes in handy to filter some entry or some data processing stuff while looping through. Here is a little example, which filters out names <= 8 characters:

Map<Integer, String> users = new HashMap<>();
users.put(1, "Nam Do");
users.put(2, "Ethan McCue");
users.put(3, "Morty Smith");
users.entrySet()
            .stream()
            .filter(entry -> entry.getValue().length() > 8)
            .forEach(entry -> System.out.println("Key: " + entry.getKey() + " -> Value: " + entry.getValue()));

Output:

Key: 2 -> Value: Ethan McCue
Key: 3 -> Value: Morty Smith

Note: The forEach() method here differs from the previous one, this forEach method takes a Consumer<? super T> instead of a BiComsumer. For each iteration, you will get the corresponding entry.

5. Using Iterator through EntrySet

You can also use the iterator() method on the EntrySet to loop through the map:

Map<Integer, String> users = new HashMap<>();
users.put(1, "Nam Do");
users.put(2, "Ethan McCue");
users.put(3, "Morty Smith");

Iterator<Map.Entry<Integer, String>> iterator = users.entrySet().iterator();
while (iterator.hasNext()) {
      Map.Entry<Integer, String> entry = iterator.next();
      System.out.println("Key: " + entry.getKey() + " -> Value: " + entry.getValue());
}

This approach will be your friend when you want to iterate through the map and remove some elements simultaneously:

while (iterator.hasNext()) {
      Map.Entry<Integer, String> entry = iterator.next();
      // remove the entry with the value of "Nam Do"
      if (entry.getValue().equals("Nam Do")) {
          iterator.remove();
      }
}

users.forEach((key, value) -> System.out.println("Key: " + key + " -> Value: " + value));

Output:

Key: 2 -> Value: Ethan McCue
Key: 3 -> Value: Morty Smith

If you’re recalcitrant enough, you might try this way to remove an element of a map, but sadly, it will raise java.util.ConcurrentModificationException exception:

for(Map.Entry<Integer, String> entry: users.entrySet()) {
    if (entry.getValue().equals("Nam Do")) {
        users.remove(entry.getKey());
    }
}

6. Using Iterator through KeySet

You can also get the Iterator on the keySet() as well:

Map<Integer, String> users = new HashMap<>();
users.put(1, "Nam Do");
users.put(2, "Ethan McCue");
users.put(3, "Morty Smith");

Iterator<Integer> iterator = users.keySet().iterator(); 
while (iterator.hasNext()) {
      Integer key = iterator.next();
      System.out.println("Key: " + key + " -> Value: " + users.get(key));
}
Previous Article
Next Article

Subscribe to my newsletter to get weekly updates

Categories

Archives