How to Iterate a HashMap in Java
Iterate Java HashMap entries using entrySet, keySet, values, forEach, and streams.
How to Iterate a HashMap in Java
A HashMap stores key-value pairs, and sooner or later you need to walk through them - to print a report, total the values, or filter entries. Java offers several idiomatic ways to do this, each suited to a slightly different need: do you want keys, values, or both? This chapter covers the four common approaches and when to reach for each.
Looping over entries with entrySet()
When you need both the key and the value, entrySet() is the most efficient choice. It returns a view of Map.Entry objects, and a single pass gives you each pair without a second lookup:
Map<String, Integer> stock = new HashMap<>();
for (Map.Entry<String, Integer> e : stock.entrySet()) {
System.out.println(e.getKey() + " -> " + e.getValue());
}This is the recommended default. Using keySet() and then calling map.get(key) inside the loop performs a redundant hash lookup per element; entrySet() avoids that entirely.
Iterating keys or values alone
If you only care about one side of each pair, ask for just that view. keySet() returns the keys and values() returns the values:
for (String key : stock.keySet()) {
System.out.println("key: " + key);
}
for (int qty : stock.values()) {
System.out.println("qty: " + qty);
}Both views are backed by the map, so they reflect its current contents without copying. Use keySet() when you genuinely don't need the values, and values() when the keys are irrelevant.
The forEach method
Since Java 8, Map has a forEach method that takes a BiConsumer, giving you the key and value as lambda parameters. It is concise and reads well for simple side effects:
stock.forEach((key, value) -> System.out.println(key + "=" + value));There is no break or continue inside a lambda, so for early exit or complex control flow a classic for loop is still clearer.
Safe removal with an Iterator
Modifying a map structurally while a for-each loop runs over it throws ConcurrentModificationException. To remove entries during traversal, use an explicit Iterator and call its remove():
Iterator<Map.Entry<String, Integer>> it = stock.entrySet().iterator();
while (it.hasNext()) {
if (it.next().getValue() < 10) {
it.remove();
}
}A modern alternative is stock.entrySet().removeIf(e -> e.getValue() < 10), which expresses the same filter in one line.
| Approach | Gives you | Best for |
|---|---|---|
entrySet() | key + value | the default; reading both |
keySet() | keys only | working with keys |
values() | values only | totals, value scans |
forEach | key + value (lambda) | concise side effects |
Iterator | key + value | removing during traversal |
What to take from the run:
- The
entrySet()loop reads each key and value in one pass and accumulatesTotal stock: 39, summing 12 + 7 + 20. keySet()prints only the keys (apple,banana,cherry) whilevalues()prints only the numbers, showing that each view exposes one side of the pair.- The
forEachlambda produces the same key=value lines as the manual loop, confirming it is a concise equivalent for simple iteration. - A
LinkedHashMapwas used so the output keeps insertion order - a plainHashMapgives no ordering guarantee, so its lines could appear in any sequence. - The
Iterator.remove()call dropsbanana(value 7, under 10) and leaves{apple=12, cherry=20}, demonstrating safe in-loop deletion without aConcurrentModificationException.
Practice
Which method lets you access both the key and the value in a single iteration without a second lookup?