--- old/src/share/classes/java/util/concurrent/ConcurrentMap.java 2013-10-03 20:30:27.595126376 -0700 +++ new/src/share/classes/java/util/concurrent/ConcurrentMap.java 2013-10-03 20:30:27.439126368 -0700 @@ -195,6 +195,39 @@ * must override this default implementation. */ @Override + default V merge(K key, V value, + BiFunction remappingFunction) { + Objects.requireNonNull(remappingFunction); + Objects.requireNonNull(value); + V oldValue = get(key); + for (;;) { + if (oldValue != null) { + V newValue = remappingFunction.apply(oldValue, value); + if (newValue != null) { + if (replace(key, oldValue, newValue)) + return newValue; + } else if (remove(key, oldValue)) { + return null; + } + oldValue = get(key); + } else { + if ((oldValue = putIfAbsent(key, value)) == null) { + return value; + } + } + } + } + + + /** + * {@inheritDoc} + * + * @implNote This implementation assumes that the ConcurrentMap cannot + * contain null values and get() returning null unambiguously means the key + * is absent. Implementations which support null values + * must override this default implementation. + */ + @Override default void replaceAll(BiFunction function) { Objects.requireNonNull(function); forEach((k,v) -> {