Java's Map interface doesn't extend Iterable directly, so you can't use a for-each loop on the map itself. Instead, you iterate over one of its three collection views: entrySet(), keySet(), or values(). Here are five practical methods.


Setup — Sample Map

import java.util.*;

Map<Integer, String> countries = new HashMap<>();
countries.put(1, "USA");
countries.put(2, "Germany");
countries.put(3, "Japan");
countries.put(4, "Brazil");
countries.put(5, "India");

Method 1: entrySet() with For-Each Loop

The most common and readable approach. Each Map.Entry gives you direct access to both key and value without a second lookup:

for (Map.Entry<Integer, String> entry : countries.entrySet()) {
    System.out.println(entry.getKey() + " → " + entry.getValue());
}

Output:

1 → USA
2 → Germany
3 → Japan
4 → Brazil
5 → India

This is the preferred approach when you need both key and value. It avoids the extra map.get(key) call that keySet() iteration requires.


Method 2: entrySet() with Iterator

Use an explicit Iterator when you need to remove entries during iteration — the only safe way to modify a map while iterating:

Iterator<Map.Entry<Integer, String>> iterator = countries.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<Integer, String> entry = iterator.next();
    System.out.println(entry.getKey() + " → " + entry.getValue());

    // Safe to remove — iterator.remove() doesn't throw ConcurrentModificationException
    if (entry.getKey() == 3) {
        iterator.remove();
    }
}

Never call map.remove() inside a for-each loop — it throws ConcurrentModificationException. An explicit iterator's remove() is the safe alternative.


Method 3: keySet() with For-Each Loop

Iterate over keys, then look up each value separately:

for (Integer key : countries.keySet()) {
    System.out.println(key + " → " + countries.get(key));
}

This works but performs an extra get() per entry. Use this when you only need the keys, or when the value lookup is intentional. For both key and value, entrySet() is more efficient.


Method 4: keySet() with Iterator

Iterator<Integer> keyIterator = countries.keySet().iterator();
while (keyIterator.hasNext()) {
    Integer key = keyIterator.next();
    System.out.println(key + " → " + countries.get(key));
}

Method 5: Java 8 forEach() — Most Concise

Java 8 added a forEach() method directly on Map that accepts a BiConsumer:

countries.forEach((key, value) ->
    System.out.println(key + " → " + value));

This is the cleanest syntax for read-only iteration. It's internally backed by entrySet(), so performance is identical. You can't call iterator.remove() inside forEach() — use method 2 if you need to modify the map during iteration.


Iterating Values Only

When you only need the values (not the keys), iterate values():

for (String country : countries.values()) {
    System.out.println(country);
}

Comparison

MethodAccess Key?Access Value?Remove During?Java Version
entrySet() for-eachYesYes (direct)No5+
entrySet() iteratorYesYes (direct)Yes5+
keySet() for-eachYesVia get()No5+
keySet() iteratorYesVia get()Yes5+
forEach() lambdaYesYes (direct)No8+
values() for-eachNoYesNo5+

Which Method Should You Use?

  • Default choice: forEach((key, value) -> ...) — cleanest syntax, Java 8+
  • Need to remove during iteration: entrySet().iterator() with iterator.remove()
  • Keys only: for (K key : map.keySet())
  • Values only: for (V value : map.values())
  • Pre-Java 8: entrySet() for-each

Summary

Iterate over a Map using one of its three views: entrySet() for both keys and values, keySet() for keys alone, or values() for values alone. For most modern code, map.forEach((k, v) -> ...) is the cleanest option. When you need to remove entries during iteration, use an explicit iterator — never map.remove() inside a for-each loop.