Modern Map Methods
Fast recall
Quick revision
Core answer
getOrDefault returns the mapped value, or a fallback only when no mapping exists. computeIfAbsent computes when a key is absent or currently maps to null, and stores a non-null result. merge inserts a value for an absent or null-mapped key, otherwise combines old and new values; a null remapping result removes the mapping. Atomicity depends on the Map implementation.Knowledge of Java 8+ Map API enhancements that make common patterns more concise and expressive
Using verbose patterns like checking containsKey() then putting, or getting then null-checking then putting, when these methods do it in one atomic operation
Show the frequency counting pattern with merge() using Integer::sum—it's much cleaner than the old get-increment-put approach
Interview-ready guide
Interview answer
getOrDefault returns a fallback only when the key has no mapping; if a HashMap key is present with a null value, the result is null. computeIfAbsent runs its function for an absent or null-mapped key and stores the result only when it is non-null. It is useful for creating a list on first use. merge stores the supplied value for an absent or null-mapped key, otherwise combines it with the old value; returning null from the remapping function removes the mapping.
These methods make intent clearer, but I do not promise one lookup or atomicity for every Map. A concurrent map may provide stronger atomic behavior for a method, subject to its documented callback restrictions.
Modern Map Methods
Direct Answer
getOrDefault returns the mapped value, or a fallback only when no mapping exists. computeIfAbsent computes when a key is absent or currently maps to null, and stores a non-null result. merge inserts a value for an absent or null-mapped key, otherwise combines old and new values; a null remapping result removes the mapping. Atomicity depends on the Map implementation.
Code Example
Three everyday patterns: merge for frequency counting, computeIfAbsent for nested maps, and getOrDefault for safe reads.
import java.util.*;
var orderCounts = new HashMap<String, Integer>();
var orders = List.of("ORDER-1", "ORDER-2", "ORDER-1", "ORDER-3", "ORDER-1");
for (var orderId : orders) {
orderCounts.merge(orderId, 1, Integer::sum); // frequency counting in one line
}
System.out.println(orderCounts); // {ORDER-1=3, ORDER-2=1, ORDER-3=1}
var userPreferences = new HashMap<Long, Map<String, String>>();
userPreferences.computeIfAbsent(123L, id -> new HashMap<>())
.put("theme", "dark"); // build the inner map only if needed
var config = Map.of("timeout", "30", "retries", "3");
var timeout = Integer.parseInt(config.getOrDefault("timeout", "60")); // safe fallback
var maxConn = Integer.parseInt(config.getOrDefault("maxConnections", "10"));
Each line replaces three or four lines of null-checking and branching from the pre-Java-8 style.
Common Mistakes & Pitfalls
- Manual get-then-null-check-then-put: writing
if (map.get(key) == null) map.put(key, new ArrayList<>());instead ofcomputeIfAbsent(key, k -> new ArrayList<>()). - Eager defaults in getOrDefault():
getOrDefault(key, expensive())always runsexpensive()even when the key exists — usecomputeIfAbsent()for lazy work. - Skipping merge for counting:
put(id, getOrDefault(id, 0) + 1)is noisier thanmerge(id, 1, Integer::sum). - Confusing computeIfAbsent with putIfAbsent:
putIfAbsentstores a pre-computed value, whilecomputeIfAbsentcomputes it lazily only when needed.
Check your understanding
Answer these without looking back at the article.
- How do you count word frequencies using Map.merge()?
- What does computeIfAbsent return?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.