Map.merge() inserts a supplied value when a key has no non-null mapping; when a non-null value already exists, it combines the old value and supplied value with a remapping function. If that function returns null, the mapping is removed. The method has been part of Java since Java 8, and its concurrency guarantees depend on the map implementation.
How Map.merge() behaves
The method takes a key, a non-null value to add, and a remapping function. If the key is absent—or maps to null—the supplied value is associated with the key and the function is not called. If the key has a non-null value, the function receives the existing value first and the supplied value second; its result becomes the new mapping.
For example, this counts occurrences by inserting 1 the first time and adding one on later calls:
Map<String, Integer> counts = new HashMap<>();
counts.merge("java", 1, Integer::sum); // stores 1
counts.merge("java", 1, Integer::sum); // stores 2
The method’s required value argument and remapping function must both be non-null. The function’s result may be null; in that case, merge() removes the key, or leaves it absent if it was absent to begin with. If the function throws an unchecked exception, that exception is rethrown and the current mapping is unchanged. See Oracle’s Java 8 Map documentation.
What the default implementation does
Oracle describes the default method with logic equivalent to this simplified code:
V oldValue = map.get(key);
V newValue = (oldValue == null) ? value
: remappingFunction.apply(oldValue, value);
if (newValue == null) map.remove(key);
else map.put(key, newValue);
This is a conceptual explanation, not a promise that every map uses exactly these internal steps. It highlights the important distinction: an absent or null-valued entry takes the supplied value directly, while an existing non-null entry is passed to the function.
Rank #2
When to use merge()
Use merge() when you have an incoming value and want to combine it with a value already stored under the same key. It works naturally for counters, concatenated strings, accumulated collections, and partial results.
counts.merge("java", 1, Integer::sum);
Map<String, String> labels = new HashMap<>();
labels.merge("status", "ready", (oldValue, newValue) -> oldValue + ", " + newValue);
Choose a different map method when the operation is not a combination:
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →putIfAbsent()fits “insert once; do not combine an existing value.”computeIfAbsent()fits “create a value only when the key is missing.”compute()is useful when the calculation needs the key as well as its current value, or when you want to handle the absent case in the function. Oracle’s Map documentation specifies thatcompute()receives the key and current value.
Does merge() make updates atomic?
Not for every Map. Oracle’s Java 8 Map specification explicitly says its default implementation makes no synchronization or atomicity guarantee. A call that looks like one operation in your code should not be assumed safe from races when multiple threads update an ordinary map.
ConcurrentMap implementations provide concurrency-related overrides, but the interface documentation warns that an implementation may retry the merge steps under contention. As a result, the remapping function may be invoked more than once. Keep it quick, deterministic, and free of external side effects; do not modify the same map from within the function. See Oracle’s Java 8 ConcurrentMap documentation.
Rank #4
ConcurrentHashMap documents its merge invocation as atomic. That is a stronger guarantee than the default Map contract; it does not make side effects inside the remapping function a sound design. See the Oracle ConcurrentHashMap documentation.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

