If the specified key is not already associated with a value or is
associated with null, associates it with the given non-null value.
Otherwise, replaces the associated value with the results of the given
remapping function, or removes if the result is null. This
method may be of use when combining multiple mapped values for a key.
For example, to either create or append a String msg to a
value mapping:
map.merge(key, msg, String::concat)
If the remapping function returns null, the mapping is removed.
If the remapping function itself throws an (unchecked) exception, the
exception is rethrown, and the current mapping is left unchanged.
The remapping function should not modify this map during computation.
key | key with which the resulting value is to be associated | |
value | the non-null value to be merged with the existing value associated with the key or, if no existing value or a null value is associated with the key, to be associated with the key | |
remappingFunction | the remapping function to recompute a value if present |
UnsupportedOperationException | if the put operation
is not supported by this map
(optional) | |
ClassCastException | if the class of the specified key or value prevents it from being stored in this map (optional) | |
IllegalArgumentException | if some property of the specified key or value prevents it from being stored in this map (optional) | |
NullPointerException | if the specified key is null and this map does not support null keys or the value or remappingFunction is null |
@implSpec
The default implementation is equivalent to performing the following
steps for this map, then returning the current value or
null if absent:
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);
The default implementation makes no guarantees about detecting if the
remapping function modifies this map during computation and, if
appropriate, reporting an error. Non-concurrent implementations should
override this method and, on a best-effort basis, throw a
ConcurrentModificationException if it is detected that the
remapping function modifies this map during computation. Concurrent
implementations should override this method and, on a best-effort basis,
throw an IllegalStateException if it is detected that the
remapping function modifies this map during computation and as a result
computation would never complete.
The default implementation makes no guarantees about synchronization
or atomicity properties of this method. Any implementation providing
atomicity guarantees must override this method and document its
concurrency properties. In particular, all implementations of
subinterface java.util.concurrent.ConcurrentMap must document
whether the remapping function is applied once atomically only if the
value is not present.
Diagram: Map Simple