src/share/classes/java/util/concurrent/ConcurrentMap.java

Print this page
rev 7360 : 8016446: Improve forEach/replaceAll for Map, HashMap, Hashtable, IdentityHashMap, WeakHashMap, TreeMap
Reviewed-by: forax, duigou, psandoz
Contributed-by: Mike Duigou <mike.duigou@oracle.com>, Remi Forax <forax@univ-mlv.fr>

*** 33,42 **** --- 33,44 ---- * http://creativecommons.org/publicdomain/zero/1.0/ */ package java.util.concurrent; import java.util.Map; + import java.util.Objects; + import java.util.function.BiFunction; /** * A {@link java.util.Map} providing additional atomic * {@code putIfAbsent}, {@code remove}, and {@code replace} methods. *
*** 181,186 **** --- 183,220 ---- * and this map does not permit null keys or values * @throws IllegalArgumentException if some property of the specified key * or value prevents it from being stored in this map */ V replace(K key, V 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 + * <strong>must</strong> override this default implementation. + */ + @Override + default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { + Objects.requireNonNull(function); + for (Map.Entry<K, V> entry : entrySet()) { + K k; + V v; + try { + k = entry.getKey(); + v = entry.getValue(); + } catch(IllegalStateException ise) { + // this usually means the entry is no longer in the map. + continue; + } + + while(!replace(k, v, function.apply(k, v))) { + // v changed or k is gone + if( (v = get(k)) == null) { + // k is no longer in the map. + break; + } + } + } + } }