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
| Method | Access Key? | Access Value? | Remove During? | Java Version |
|---|---|---|---|---|
entrySet() for-each | Yes | Yes (direct) | No | 5+ |
entrySet() iterator | Yes | Yes (direct) | Yes | 5+ |
keySet() for-each | Yes | Via get() | No | 5+ |
keySet() iterator | Yes | Via get() | Yes | 5+ |
forEach() lambda | Yes | Yes (direct) | No | 8+ |
values() for-each | No | Yes | No | 5+ |
Which Method Should You Use?
- Default choice:
forEach((key, value) -> ...)— cleanest syntax, Java 8+ - Need to remove during iteration:
entrySet().iterator()withiterator.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.