src/share/classes/java/util/Map.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>


 528      * <pre> {@code
 529      * for ((Map.Entry<K, V> entry : map.entrySet())
 530      *     action.accept(entry.getKey(), entry.getValue());
 531      * }</pre>
 532      *
 533      * @param action The action to be performed for each entry
 534      * @throws NullPointerException if the specified action is null
 535      * @throws ConcurrentModificationException if an entry is found to be
 536      * removed during iteration
 537      * @since 1.8
 538      */
 539     default void forEach(BiConsumer<? super K, ? super V> action) {
 540         Objects.requireNonNull(action);
 541         for (Map.Entry<K, V> entry : entrySet()) {
 542             K k;
 543             V v;
 544             try {
 545                 k = entry.getKey();
 546                 v = entry.getValue();
 547             } catch(IllegalStateException ise) {

 548                 throw new ConcurrentModificationException(ise);
 549             }
 550             action.accept(k, v);
 551         }
 552     }
 553 
 554     /**
 555      * Replaces each entry's value with the result of invoking the given
 556      * function on that entry, in the order entries are returned by an entry
 557      * set iterator, until all entries have been processed or the function
 558      * throws an exception.
 559      *
 560      * <p>The default implementation makes no guarantees about synchronization
 561      * or atomicity properties of this method. Any implementation providing
 562      * atomicity guarantees must override this method and document its
 563      * concurrency properties.
 564      *
 565      * @implSpec
 566      * <p>The default implementation is equivalent to, for this {@code map}:
 567      * <pre> {@code


 582      *         (<a href="Collection.html#optional-restrictions">optional</a>)
 583      * @throws NullPointerException if function or a replacement value is null,
 584      *         and this map does not permit null keys or values
 585      *         (<a href="Collection.html#optional-restrictions">optional</a>)
 586      * @throws IllegalArgumentException if some property of a replacement value
 587      *         prevents it from being stored in this map
 588      *         (<a href="Collection.html#optional-restrictions">optional</a>)
 589      * @throws ConcurrentModificationException if an entry is found to be
 590      * removed during iteration
 591      * @since 1.8
 592      */
 593     default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
 594         Objects.requireNonNull(function);
 595         for (Map.Entry<K, V> entry : entrySet()) {
 596             K k;
 597             V v;
 598             try {
 599                 k = entry.getKey();
 600                 v = entry.getValue();
 601             } catch(IllegalStateException ise) {











 602                 throw new ConcurrentModificationException(ise);
 603             }
 604             entry.setValue(function.apply(k, v));
 605         }
 606     }
 607 
 608     /**
 609      * If the specified key is not already associated with a value (or is mapped
 610      * to {@code null}) associates it with the given value and returns
 611      * {@code null}, else returns the current value.
 612      *
 613      * <p>The default implementation makes no guarantees about synchronization
 614      * or atomicity properties of this method. Any implementation providing
 615      * atomicity guarantees must override this method and document its
 616      * concurrency properties.
 617      *
 618      * @implSpec
 619      * The default implementation is equivalent to, for this {@code
 620      * map}:
 621      *
 622      * <pre> {@code
 623      * if (map.get(key) == null)
 624      *     return map.put(key, value);




 528      * <pre> {@code
 529      * for ((Map.Entry<K, V> entry : map.entrySet())
 530      *     action.accept(entry.getKey(), entry.getValue());
 531      * }</pre>
 532      *
 533      * @param action The action to be performed for each entry
 534      * @throws NullPointerException if the specified action is null
 535      * @throws ConcurrentModificationException if an entry is found to be
 536      * removed during iteration
 537      * @since 1.8
 538      */
 539     default void forEach(BiConsumer<? super K, ? super V> action) {
 540         Objects.requireNonNull(action);
 541         for (Map.Entry<K, V> entry : entrySet()) {
 542             K k;
 543             V v;
 544             try {
 545                 k = entry.getKey();
 546                 v = entry.getValue();
 547             } catch(IllegalStateException ise) {
 548                 // this usually means the entry is no longer in the map.
 549                 throw new ConcurrentModificationException(ise);
 550             }
 551             action.accept(k, v);
 552         }
 553     }
 554 
 555     /**
 556      * Replaces each entry's value with the result of invoking the given
 557      * function on that entry, in the order entries are returned by an entry
 558      * set iterator, until all entries have been processed or the function
 559      * throws an exception.
 560      *
 561      * <p>The default implementation makes no guarantees about synchronization
 562      * or atomicity properties of this method. Any implementation providing
 563      * atomicity guarantees must override this method and document its
 564      * concurrency properties.
 565      *
 566      * @implSpec
 567      * <p>The default implementation is equivalent to, for this {@code map}:
 568      * <pre> {@code


 583      *         (<a href="Collection.html#optional-restrictions">optional</a>)
 584      * @throws NullPointerException if function or a replacement value is null,
 585      *         and this map does not permit null keys or values
 586      *         (<a href="Collection.html#optional-restrictions">optional</a>)
 587      * @throws IllegalArgumentException if some property of a replacement value
 588      *         prevents it from being stored in this map
 589      *         (<a href="Collection.html#optional-restrictions">optional</a>)
 590      * @throws ConcurrentModificationException if an entry is found to be
 591      * removed during iteration
 592      * @since 1.8
 593      */
 594     default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
 595         Objects.requireNonNull(function);
 596         for (Map.Entry<K, V> entry : entrySet()) {
 597             K k;
 598             V v;
 599             try {
 600                 k = entry.getKey();
 601                 v = entry.getValue();
 602             } catch(IllegalStateException ise) {
 603                 // this usually means the entry is no longer in the map.
 604                 throw new ConcurrentModificationException(ise);
 605             }
 606 
 607             // ise thrown from function is not a cme.
 608             v = function.apply(k, v);
 609 
 610             try {
 611                 entry.setValue(v);
 612             } catch(IllegalStateException ise) {
 613                 // this usually means the entry is no longer in the map.
 614                 throw new ConcurrentModificationException(ise);
 615             }

 616         }
 617     }
 618 
 619     /**
 620      * If the specified key is not already associated with a value (or is mapped
 621      * to {@code null}) associates it with the given value and returns
 622      * {@code null}, else returns the current value.
 623      *
 624      * <p>The default implementation makes no guarantees about synchronization
 625      * or atomicity properties of this method. Any implementation providing
 626      * atomicity guarantees must override this method and document its
 627      * concurrency properties.
 628      *
 629      * @implSpec
 630      * The default implementation is equivalent to, for this {@code
 631      * map}:
 632      *
 633      * <pre> {@code
 634      * if (map.get(key) == null)
 635      *     return map.put(key, value);