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;
+ }
+ }
+ }
+ }
}