changeset 7612:35063788660b

Spruce up Map docs.
author psandoz
date Tue, 12 Mar 2013 12:29:50 +0100
parents cfc1cdcbd8b5
children 571a828ffc94
files src/share/classes/java/util/Collections.java src/share/classes/java/util/Map.java
diffstat 2 files changed, 176 insertions(+), 114 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/Collections.java	Tue Mar 12 11:28:41 2013 +0100
+++ b/src/share/classes/java/util/Collections.java	Tue Mar 12 12:29:50 2013 +0100
@@ -2127,8 +2127,8 @@
             synchronized (mutex) {return m.toString();}
         }
 
-        public void forEach(BiConsumer<? super K, ? super V> consumer) {
-            synchronized (mutex) {m.forEach(consumer);}
+        public void forEach(BiConsumer<? super K, ? super V> action) {
+            synchronized (mutex) {m.forEach(action);}
         }
         public void replaceAll(BiFunction<K, V, V> function) {
             synchronized (mutex) {m.replaceAll(function);}
--- a/src/share/classes/java/util/Map.java	Tue Mar 12 11:28:41 2013 +0100
+++ b/src/share/classes/java/util/Map.java	Tue Mar 12 12:29:50 2013 +0100
@@ -483,25 +483,76 @@
     // Defaultable methods
 
     /**
-     * Execute the specified {@code BiConsumer} with the key and value of
-     * each entry in this map.
+     * Performs the given action on each entry in this map, in the
+     * order entries are returned by an entry set iterator, until all entries
+     * have been processed or the action throws an {@code Exception}.
+     * Exceptions thrown by the action are relayed to the caller.
      *
-     * @param block the {@code BiConsumer} to which entries will be applied
+     * <p>The default implementation should be overridden by implementations if
+     * they can provide a more performant implementation than an iterator-based
+     * one.
+     *
+     * <p>The default implementation makes no guarantees about
+     * synchronization or atomicity properties of this method. Any
+     * class overriding this method must specify its concurrency
+     * properties. In particular, all implementations of
+     * subinterface {@link java.util.concurrent.ConcurrentMap}
+     * must ensure that this operation is performed atomically.
+     *
+     * @implSpec
+     * <p>The default implementation is equivalent to, for this {@code map}:
+     * <pre> {@code
+     *     for ((Map.Entry<K, V> entry : map.entrySet())
+     *         action.accept(entry.getKey(), entry.getValue());
+     * }</pre>
+     *
+     * @param action The action to be performed for each entry
+     * @throws NullPointerException if the specified action is null
+     * @since 1.8
      */
-    default void forEach(BiConsumer<? super K, ? super V> block) {
-        Objects.requireNonNull(block);
+    default void forEach(BiConsumer<? super K, ? super V> action) {
+        Objects.requireNonNull(action);
         for (Map.Entry<K, V> entry : entrySet()) {
-            block.accept(entry.getKey(), entry.getValue());
+            action.accept(entry.getKey(), entry.getValue());
         }
     }
 
     /**
-     * Apply the specified function to each entry in this map, replacing
+     * Apply the specified function to each entry in this map, in the
+     * order entries are returned by an entry set iterator, and replacing
      * each entry's value with the result of calling the function's
      * {@link BiFunction#apply(Object, Object) BiFunction.apply(K key, V, value)}
-     * method with the current entry's key and value.
+     * method with the current entry's key and value.  Exceptions thrown by the
+     * function are relayed to the caller.
+     *
+     * <p>The default implementation makes no guarantees about
+     * synchronization or atomicity properties of this method. Any
+     * class overriding this method must specify its concurrency
+     * properties. In particular, all implementations of
+     * subinterface {@link java.util.concurrent.ConcurrentMap}
+     * must ensure that this operation is performed atomically.
+     *
+     * @implSpec
+     * <p>The default implementation is equivalent to, for this {@code map}:
+     * <pre> {@code
+     *     for ((Map.Entry<K, V> entry : map.entrySet())
+     *         entry.setValue(function.apply(entry.getKey(), entry.getValue()));
+     * }</pre>
      *
      * @param function the function to apply to each entry
+     * @throws UnsupportedOperationException if the <tt>put</tt> operation
+     *         is not supported by this map
+     * @throws ClassCastException if the class of the specified value
+     *         prevents it from being stored in the backing map
+     * @throws NullPointerException if the specified function is null, or the
+     *         specified key or value is null, 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
+     * @throws IllegalStateException implementations may, but are not
+     *         required to, throw this exception if the entry has been
+     *         removed from the backing map.
+     * @since 1.8
      */
     default void replaceAll(BiFunction<K, V, V> function) {
         Objects.requireNonNull(function);
@@ -515,7 +566,15 @@
      * associates it with the given value and returns {@code null},
      * else returns the current value.
      *
-     * <p>The default implementation is equivalent to, for this {@code
+     * <p>The default implementation makes no guarantees about
+     * synchronization or atomicity properties of this method. Any
+     * class overriding this method must specify its concurrency
+     * properties. In particular, all implementations of
+     * subinterface {@link java.util.concurrent.ConcurrentMap}
+     * must ensure that this operation is performed atomically.
+     *
+     * @implSpec
+     * The default implementation is equivalent to, for this {@code
      * map}:
      *
      *  <pre> {@code
@@ -524,13 +583,6 @@
      * else
      *   return map.get(key);}</pre>
      *
-     * <p>The default implementation makes no guarantees about
-     * synchronization or atomicity properties of this method. Any
-     * class overriding this method must specify its concurrency
-     * properties. In particular, all implementations of
-     * subinterface {@link java.util.concurrent.ConcurrentMap}
-     * must ensure that this operation is performed atomically.
-     *
      * @param key key with which the specified value is to be associated
      * @param value value to be associated with the specified key
      * @return the previous value associated with the specified key, or
@@ -546,6 +598,7 @@
      *         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
+     * @since 1.8
      */
     default V putIfAbsent(K key, V value) {
         return containsKey(key) ? get(key) : put(key, value);
@@ -555,15 +608,6 @@
      * Removes the entry for the specified key only if it is currently
      * mapped to the specified value.
      *
-     * <p>The default implementation is equivalent to, for this {@code map}:
-     *
-     *  <pre> {@code
-     * if (map.containsKey(key) && map.get(key).equals(value)) {
-     *   map.remove(key);
-     *   return true;
-     * } else
-     *   return false;}</pre>
-     *
      * <p>The default implementation makes no guarantees about
      * synchronization or atomicity properties of this method. Any
      * class overriding this method must specify its concurrency
@@ -571,6 +615,16 @@
      * subinterface {@link java.util.concurrent.ConcurrentMap}
      * must ensure that this operation is performed atomically.
      *
+     * @implSpec
+     * The default implementation is equivalent to, for this {@code map}:
+     *
+     * <pre> {@code
+     * if (map.containsKey(key) && map.get(key).equals(value)) {
+     *   map.remove(key);
+     *   return true;
+     * } else
+     *   return false;}</pre>
+     *
      * @param key key with which the specified value is associated
      * @param value value expected to be associated with the specified key
      * @return <tt>true</tt> if the value was removed
@@ -582,6 +636,7 @@
      * @throws NullPointerException if the specified key or value is null,
      *         and this map does not permit null keys or values
      *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @since 1.8
      */
     default boolean remove(Object key, Object value) {
         if (!containsKey(key) || !get(key).equals(value))
@@ -594,15 +649,6 @@
      * Replaces the entry for the specified key only if currently
      * mapped to the specified value.
      *
-     * <p>The default implementation is equivalent to, for this {@code map}:
-     *
-     *  <pre> {@code
-     * if (map.containsKey(key) && map.get(key).equals(oldValue)) {
-     *   map.put(key, newValue);
-     *   return true;
-     * } else
-     *   return false;}</pre>
-     *
      * <p>The default implementation makes no guarantees about
      * synchronization or atomicity properties of this method. Any
      * class overriding this method must specify its concurrency
@@ -610,6 +656,16 @@
      * subinterface {@link java.util.concurrent.ConcurrentMap}
      * must ensure that this operation is performed atomically.
      *
+     * @implSpec
+     * The default implementation is equivalent to, for this {@code map}:
+     *
+     * <pre> {@code
+     * if (map.containsKey(key) && map.get(key).equals(oldValue)) {
+     *   map.put(key, newValue);
+     *   return true;
+     * } else
+     *   return false;}</pre>
+     *
      * @param key key with which the specified value is associated
      * @param oldValue value expected to be associated with the specified key
      * @param newValue value to be associated with the specified key
@@ -622,6 +678,7 @@
      *         and this map does not permit null keys or values
      * @throws IllegalArgumentException if some property of a specified key
      *         or value prevents it from being stored in this map
+     * @since 1.8
      */
     default boolean replace(K key, V oldValue, V newValue) {
         if (!containsKey(key) || !get(key).equals(oldValue))
@@ -634,14 +691,6 @@
      * Replaces the entry for the specified key only if it is
      * currently mapped to some value.
      *
-     * <p>The default implementation is equivalent to, for this {@code map}:
-     *
-     *  <pre> {@code
-     * if (map.containsKey(key)) {
-     *   return map.put(key, value);
-     * } else
-     *   return null;}</pre>
-     *
      * <p>The default implementation makes no guarantees about
      * synchronization or atomicity properties of this method. Any
      * class overriding this method must specify its concurrency
@@ -649,6 +698,15 @@
      * subinterface {@link java.util.concurrent.ConcurrentMap}
      * must ensure that this operation is performed atomically.
      *
+     * @implSpec
+     * The default implementation is equivalent to, for this {@code map}:
+     *
+     * <pre> {@code
+     * if (map.containsKey(key)) {
+     *   return map.put(key, value);
+     * } else
+     *   return null;}</pre>
+     *
      * @param key key with which the specified value is associated
      * @param value value to be associated with the specified key
      * @return the previous value associated with the specified key, or
@@ -664,6 +722,7 @@
      *         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
+     * @since 1.8
      */
     default V replace(K key, V value) {
         return containsKey(key) ? put(key, value) : null;
@@ -675,24 +734,13 @@
      * the given mapping function and enters it into this map unless
      * {@code null}.
      *
-     * <p>The default implementation is equivalent to the following
-     * steps for this {@code map}, then returning the current value or
-     * {@code null} if now absent:
-     *
-     * <pre> {@code
-     * if (map.get(key) == null) {
-     *   V newValue = mappingFunction.apply(key);
-     *   if (newValue != null)
-     *      map.putIfAbsent(key, newValue);
-     * }}</pre>
-     *
-     * If the function returns {@code null} no mapping is recorded. If
+     * <p>If the function returns {@code null} no mapping is recorded. If
      * the function itself throws an (unchecked) exception, the
      * exception is rethrown, and no mapping is recorded.  The most
      * common usage is to construct a new object serving as an initial
      * mapped value or memoized result, as in:
      *
-     *  <pre> {@code
+     * <pre> {@code
      * map.computeIfAbsent(key, k -> new Value(f(k)));}</pre>
      *
      * <p>The default implementation makes no guarantees about
@@ -706,6 +754,18 @@
      * whether and how this method distinguishes absence from null
      * mappings.
      *
+     * @implSpec
+     * The default implementation is equivalent to the following
+     * steps for this {@code map}, then returning the current value or
+     * {@code null} if now absent:
+     *
+     * <pre> {@code
+     * if (map.get(key) == null) {
+     *   V newValue = mappingFunction.apply(key);
+     *   if (newValue != null)
+     *      map.putIfAbsent(key, newValue);
+     * }}</pre>
+     *
      * @param key key with which the specified value is to be associated
      * @param mappingFunction the function to compute a value
      * @return the current (existing or computed) value associated with
@@ -717,8 +777,7 @@
      *         is not supported by this map
      * @throws ClassCastException if the class of the specified key or value
      *         prevents it from being stored in this map
-     * @throws RuntimeException or Error if the mappingFunction does so,
-     *         in which case the mapping is left unestablished
+     * @since 1.8
      */
     default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
         V v, newValue;
@@ -732,7 +791,24 @@
      * attempts to compute a new mapping given the key and its current
      * mapped value.
      *
-     * <p>The default implementation is equivalent to performing the
+     * <p>If the function returns {@code null}, the mapping is removed (or
+     * remains absent if initially absent).  If the function itself throws an
+     * (unchecked) exception, the exception is rethrown, and the current mapping
+     * is left unchanged.
+     *
+     * <p>The default implementation makes no guarantees about
+     * synchronization or atomicity properties of this method or the
+     * application of the remapping function. Any class overriding
+     * this method must specify its concurrency properties.  In
+     * particular, all implementations of subinterface {@link
+     * java.util.concurrent.ConcurrentMap} must document whether the
+     * function is applied once atomically only if the value is
+     * present.  Any class that permits null values must document
+     * whether and how this method distinguishes absence from null
+     * mappings.
+     *
+     * @implSpec
+     * The default implementation is equivalent to performing the
      * following steps for this {@code map}, then returning the
      * current value or {@code null} if now absent:
      *
@@ -747,22 +823,7 @@
      * }}</pre>
      *
      * In concurrent contexts, the default implementation may retry
-     * these steps when multiple threads attempt updates.  If the
-     * function returns {@code null}, the mapping is removed (or
-     * remains absent if initially absent).  If the function itself
-     * throws an (unchecked) exception, the exception is rethrown, and
-     * the current mapping is left unchanged.
-     *
-     * <p>The default implementation makes no guarantees about
-     * synchronization or atomicity properties of this method or the
-     * application of the remapping function. Any class overriding
-     * this method must specify its concurrency properties.  In
-     * particular, all implementations of subinterface {@link
-     * java.util.concurrent.ConcurrentMap} must document whether the
-     * function is applied once atomically only if the value is
-     * present.  Any class that permits null values must document
-     * whether and how this method distinguishes absence from null
-     * mappings.
+     * these steps when multiple threads attempt updates.
      *
      * @param key key with which the specified value is to be associated
      * @param remappingFunction the function to compute a value
@@ -774,8 +835,7 @@
      *         is not supported by this map
      * @throws ClassCastException if the class of the specified key or value
      *         prevents it from being stored in this map
-     * @throws RuntimeException or Error if the remappingFunction does so,
-     *         in which case the mapping is unchanged
+     * @since 1.8
      */
     default V computeIfPresent(K key,
                                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
@@ -802,7 +862,23 @@
      * map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre>
      * (Method {@link #merge} is often simpler to use for such purposes.)
      *
-     * <p>The default implementation is equivalent to
+     * <p>If the function returns {@code null}, the mapping is removed (or
+     * remains absent if initially absent).  If the function itself throws an
+     * (unchecked) exception, the exception is rethrown, and the current mapping
+     * is left unchanged.
+     *
+     * <p>The default implementation makes no guarantees about
+     * synchronization or atomicity properties of this method or the
+     * application of the remapping function. Any class overriding
+     * this method must specify its concurrency properties.  In
+     * particular, all implementations of subinterface {@link
+     * java.util.concurrent.ConcurrentMap} must document whether the
+     * function is applied exactly once atomically. Any class that
+     * permits null values must document whether and how this method
+     * distinguishes absence from null mappings.
+     *
+     * @implSpec
+     * The default implementation is equivalent to
      * performing the following steps for this {@code map}, then
      * returning the current value or {@code null} if absent:
      *
@@ -816,21 +892,7 @@
      * }</pre>
      *
      * In concurrent contexts, the default implementation may retry
-     * these steps when multiple threads attempt updates.  If the
-     * function returns {@code null}, the mapping is removed (or
-     * remains absent if initially absent).  If the function itself
-     * throws an (unchecked) exception, the exception is rethrown, and
-     * the current mapping is left unchanged.
-     *
-     * <p>The default implementation makes no guarantees about
-     * synchronization or atomicity properties of this method or the
-     * application of the remapping function. Any class overriding
-     * this method must specify its concurrency properties.  In
-     * particular, all implementations of subinterface {@link
-     * java.util.concurrent.ConcurrentMap} must document whether the
-     * function is applied exactly once atomically. Any class that
-     * permits null values must document whether and how this method
-     * distinguishes absence from null mappings.
+     * these steps when multiple threads attempt updates.
      *
      * @param key key with which the specified value is to be associated
      * @param remappingFunction the function to compute a value
@@ -842,8 +904,7 @@
      *         is not supported by this map
      * @throws ClassCastException if the class of the specified key or value
      *         prevents it from being stored in this map
-     * @throws RuntimeException or Error if the remappingFunction does so,
-     *         in which case the mapping is unchanged
+     * @since 1.8
      */
     default V compute(K key,
                       BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
@@ -871,7 +932,23 @@
      * <pre> {@code
      * map.merge(key, msg, String::concat)}</pre>
      *
-     * <p>The default implementation is equivalent to performing the
+     * <p>If the function returns {@code null}, the mapping is removed (or
+     * remains absent if initially absent).  If the function itself throws an
+     * (unchecked) exception, the exception is rethrown, and the current mapping
+     * is left unchanged.
+     *
+     * <p>The default implementation makes no guarantees about
+     * synchronization or atomicity properties of this method or the
+     * application of the remapping function. Any class overriding
+     * this method must specify its concurrency properties.  In
+     * particular, all implementations of subinterface {@link
+     * java.util.concurrent.ConcurrentMap} must document whether the
+     * function is applied exactly once atomically. Any class that
+     * permits null values must document whether and how this method
+     * distinguishes absence from null mappings.
+     *
+     * @implSpec
+     * The default implementation is equivalent to performing the
      * following steps for this {@code map}, then returning the
      * current value or {@code null} if absent:
      *
@@ -888,21 +965,7 @@
      * }</pre>
      *
      * In concurrent contexts, the default implementation may retry
-     * these steps when multiple threads attempt updates.  If the
-     * function returns {@code null}, the mapping is removed (or
-     * remains absent if initially absent).  If the function itself
-     * throws an (unchecked) exception, the exception is rethrown, and
-     * the current mapping is left unchanged.
-     *
-     * <p>The default implementation makes no guarantees about
-     * synchronization or atomicity properties of this method or the
-     * application of the remapping function. Any class overriding
-     * this method must specify its concurrency properties.  In
-     * particular, all implementations of subinterface {@link
-     * java.util.concurrent.ConcurrentMap} must document whether the
-     * function is applied exactly once atomically. Any class that
-     * permits null values must document whether and how this method
-     * distinguishes absence from null mappings.
+     * these steps when multiple threads attempt updates.
      *
      * @param key key with which the specified value is to be associated
      * @param value the value to use if absent
@@ -911,8 +974,7 @@
      * @throws NullPointerException if the specified key is null and
      *         this map does not support null keys, or the
      *         remappingFunction is null
-     * @throws RuntimeException or Error if the remappingFunction does so,
-     *         in which case the mapping is unchanged
+     * @since 1.8
      */
     default V merge(K key, V value,
                     BiFunction<? super V, ? super V, ? extends V> remappingFunction) {