W3docs

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.

ApproachGives youBest for
entrySet()key + valuethe default; reading both
keySet()keys onlyworking with keys
values()values onlytotals, value scans
forEachkey + value (lambda)concise side effects
Iteratorkey + valueremoving during traversal
java— editable, runs on the server

What to take from the run:

  • The entrySet() loop reads each key and value in one pass and accumulates Total stock: 39, summing 12 + 7 + 20.
  • keySet() prints only the keys (apple, banana, cherry) while values() prints only the numbers, showing that each view exposes one side of the pair.
  • The forEach lambda produces the same key=value lines as the manual loop, confirming it is a concise equivalent for simple iteration.
  • A LinkedHashMap was used so the output keeps insertion order - a plain HashMap gives no ordering guarantee, so its lines could appear in any sequence.
  • The Iterator.remove() call drops banana (value 7, under 10) and leaves {apple=12, cherry=20}, demonstrating safe in-loop deletion without a ConcurrentModificationException.

Practice

Practice

Which method lets you access both the key and the value in a single iteration without a second lookup?