skip to content

Map.Entry & Default/Compute Methods

Map.Entry for entrySet traversal plus the modern conveniences: getOrDefault, putIfAbsent, computeIfAbsent, compute and merge. computeIfAbsent for building multi-maps and merge for counting are the idioms interviewers expect to see.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

6

What is Map.Entry and how do you use it to iterate over a Map's key-value pairs?

level: juniorimportance: must knowfreq 70%

answer

  1. entrySet() = both key and value in one pass
  2. keySet()+get() = double lookup, avoid
  3. setValue() writes through to the map
  4. entry valid only during its iteration step
  5. Map.entry() = immutable, Java 9+

basics

~20 s

Map.Entry represents one key-value pair in a Map. You get all pairs with map.entrySet() and loop over them, calling getKey() and getValue() on each entry. This is the cheapest way to read both key and value together.

solid answer

~40 s

Map.Entry is a nested interface representing a single key/value pair held by a Map. The idiomatic traversal is `for (Map.Entry<K,V> e : map.entrySet())`, then `e.getKey()` and `e.getValue()`. This is more efficient than iterating keySet() and calling map.get(key) for each key, which does a second lookup per entry. An entry's `setValue(v)` writes through to the backing map, but only while you hold the entry during iteration; the entry is generally not valid to reuse after the iterator advances or the map is structurally modified. Since Java 9, `Map.entry(k, v)` creates an immutable standalone entry (useful for Map.ofEntries). For stable iteration order use LinkedHashMap or TreeMap; HashMap order is unspecified.

go deeper

for a junior

Can write the for-each over entrySet() and call getKey()/getValue() correctly.

for a middle

Explains why entrySet() avoids the double lookup of keySet()+get() and knows setValue writes through.

for a senior

Discusses entry validity during iteration, iteration-order guarantees per implementation, and immutable Map.entry.

for a principal

Reasons about view semantics, fail-fast iterators, and when to prefer streams or forEach over explicit entry iteration for clarity vs. performance.

### What a Map is A **Map** is a collection that stores data as **key-value pairs**: each unique *key* maps to one *value* (like a dictionary where the word is the key and the definition is the value). Java's `java.util.Map` is the interface; common implementations are `HashMap`, `LinkedHashMap`, and `TreeMap`. ### What Map.Entry is A Map needs a way to hand you *one* pair at a time. `Map.Entry<K,V>` is a **nested interface** (declared inside `Map`) that represents exactly one key-value pair. Its core methods are: - `getKey()` — returns the key of this pair. - `getValue()` — returns the value of this pair. - `setValue(V newValue)` — changes the value; this **writes through** to the underlying map (the map actually changes). ### Getting the entries: entrySet() `map.entrySet()` returns a `Set<Map.Entry<K,V>>` — a view (not a copy) of all the pairs. "View" means it is backed by the map: it reflects the map's current contents. You loop over it: ```java for (Map.Entry<String,Integer> e : map.entrySet()) { System.out.println(e.getKey() + "=" + e.getValue()); } ``` ### Why entrySet() beats keySet() An alternative is to loop over `map.keySet()` (just the keys) and call `map.get(key)` for each. That performs **two operations per pair**: one to produce the key and one hash lookup to fetch the value. `entrySet()` gives you both at once, so it does roughly **half the work** on a HashMap — meaningfully cheaper on large maps. ### setValue write-through and validity During iteration you may call `e.setValue(x)` to update that pair in place — legal and efficient. But an `Entry` obtained from iteration is only guaranteed valid **for that step**: after the iterator moves on, or if the map is structurally modified (a key added/removed) outside the iterator, the entry's behavior is undefined. You should not stash entries in a list and read them later expecting them to stay live. ### Immutable standalone entries (Java 9+) `Map.entry(key, value)` creates a **self-contained, immutable** entry not tied to any map. It rejects nulls and throws on `setValue`. It is mainly used with `Map.ofEntries(...)` to build small immutable maps. ### Iteration order The order in which `entrySet()` yields pairs depends on the implementation: `HashMap` is **unordered/unspecified**, `LinkedHashMap` preserves insertion (or access) order, and `TreeMap` yields keys in sorted order. Don't rely on HashMap order.

  • Why is iterating entrySet() generally faster than keySet() then map.get()?
    entrySet() yields the key and value together, so it avoids the extra hash lookup that map.get(key) performs for every key — roughly halving the work on a HashMap.
  • What does Map.entry(k, v) give you that an iteration entry does not?
    An immutable, standalone entry not backed by any map: it rejects null key/value and throws UnsupportedOperationException on setValue; useful with Map.ofEntries.

saying these in an interview costs you the question

  • Claiming keySet()+get() is just as fast as entrySet()
  • Thinking setValue() only changes a copy, not the map
  • Assuming HashMap iterates in insertion or sorted order
  • Storing iteration entries and reading them after the loop

context

open as a page

How do getOrDefault and putIfAbsent simplify common Map access patterns, and how do they differ?

level: juniorimportance: must knowfreq 68%

basics

~20 s

getOrDefault(key, fallback) returns the value if the key exists, otherwise the fallback — without changing the map. putIfAbsent(key, value) only stores the value if the key is missing (or maps to null) and returns the previous value, leaving an existing value untouched.

open as a page

What does computeIfAbsent do, and why is it the idiomatic way to build multimaps (Map of List)?

level: middleimportance: must knowfreq 75%

basics

~20 s

computeIfAbsent(key, fn) returns the existing value for key, or if it is missing, runs fn to create a value, stores it, and returns it. It is perfect for grouping: it makes the empty list once, then you add to it.

open as a page

How do compute and computeIfPresent differ from computeIfAbsent, and when would you use each?

level: middleimportance: should knowfreq 58%

basics

~20 s

computeIfAbsent runs only when the key is missing. computeIfPresent runs only when the key already has a value. compute always runs and receives the current value (or null). In all three, returning null removes (or skips creating) the entry.

open as a page

What is Map.merge and how does it express fold-style updates like frequency counting?

level: middleimportance: should knowfreq 62%

basics

~20 s

merge(key, value, fn) stores value if the key is absent; if the key already has a value, it calls fn(oldValue, value) and stores the result. It is the clean way to count: counts.merge(word, 1, Integer::sum).

open as a page

Why are the compute/merge family the correct tools for thread-safe accumulation on a ConcurrentHashMap, and what are the pitfalls?

level: seniorimportance: should knowfreq 48%

basics

~10 s

On a ConcurrentHashMap, compute, computeIfAbsent, computeIfPresent, and merge perform the read-modify-write for a key as one atomic step, so two threads can't lose each other's updates. Plain get-then-put can; that's the bug they fix.

open as a page