HashMap Iteration
entrySet() for key-value pairs, keySet() for keys only, values() for values only, forEach() lambda. computeIfAbsent trick for grouping — avoids manual null-check when building Map<K, List<V>>.
How It Works
HashMap exposes three iteration views: entrySet() yields key-value pairs, keySet() yields keys, and values() yields values, plus a forEach((k, v) -> ...) lambda form. When both key and value are needed, iterate entrySet — looping keySet and calling get(key) inside performs a redundant hash lookup per element. All views are live: structural changes during iteration throw ConcurrentModificationException unless made through the iterator's own remove.
The grouping idiom is computeIfAbsent: map.computeIfAbsent(key, k -> new ArrayList<>()).add(item) creates the bucket list on first sight of a key and appends thereafter, replacing the manual null-check dance. This single line is the backbone of solutions like Group Anagrams and adjacency-list construction.
Step-by-Step Visualization
Code
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
// ─── Iteration options ────────────────────────────────────────
// entrySet — key+value at once (prefer this)
for (Map.Entry<String, Integer> e : map.entrySet())
System.out.println(e.getKey() + " → " + e.getValue());
// keySet — keys only (needs extra map.get() per key)
for (String key : map.keySet()) { /* map.get(key) */ }
// values — values only
for (int val : map.values()) { /* use val */ }
// forEach lambda — cleanest for read-only pass
map.forEach((k, v) -> System.out.println(k + "=" + v));
// ─── Safe removal during iteration ───────────────────────────
Iterator<Map.Entry<String,Integer>> it = map.entrySet().iterator();
while (it.hasNext()) {
if (it.next().getValue() < 2) it.remove(); // safe; NOT map.remove()
}
// ─── Group anagrams: computeIfAbsent pattern ─────────────────
Map<String, List<String>> anagrams = new HashMap<>();
for (String word : words) {
char[] c = word.toCharArray();
Arrays.sort(c);
anagrams.computeIfAbsent(new String(c), k -> new ArrayList<>()).add(word);
}Tips & Gotchas
Practice Problems
- 1Group Anagrams
- 2Top K Frequent Elements
- 3Find All Anagrams in a String
- 4Employee Importance
About the HashMap & HashSet API Pattern
The complete Java API for HashMap and HashSet — constructors, every core method, iteration patterns, and set-based conversions. These are your building blocks for every hash-based problem.
If brute force is O(n²) because of a nested search, a hash map usually drops it to O(n). The tradeoff is O(n) extra space.
Common Hash Map Interview Problems
- Two Sum
- Subarray Sum Equals K
- Top K Frequent Elements
- LRU Cache
- Group Anagrams
- Longest Consecutive Sequence
Frequently Asked Questions
Why prefer entrySet over keySet when I need values too?
Iterating keySet and calling get(key) inside the loop re-hashes every key, doubling the lookup work. entrySet hands you each key and value together in one pass, which is both faster and clearer.
How do I safely remove entries while iterating a HashMap?
Use an explicit Iterator over entrySet and call iterator.remove(), or use map.entrySet().removeIf(predicate) / values().removeIf(...). Calling map.remove directly inside a for-each loop throws ConcurrentModificationException.
What does computeIfAbsent buy over putIfAbsent for grouping?
computeIfAbsent returns the existing or newly created value, letting you chain .add(item) immediately, and it only constructs the new list when the key is genuinely absent. putIfAbsent evaluates its value argument eagerly and returns the previous value or null, making the grouping idiom clumsier.