• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package java.util;
27 
28 import java.util.function.BiConsumer;
29 import java.util.function.BiFunction;
30 import java.util.function.Function;
31 import java.io.Serializable;
32 
33 // BEGIN android-note
34 // removed link to collections framework docs
35 // removed java 9 methods
36 // END android-note
37 
38 /**
39  * An object that maps keys to values.  A map cannot contain duplicate keys;
40  * each key can map to at most one value.
41  *
42  * <p>This interface takes the place of the {@code Dictionary} class, which
43  * was a totally abstract class rather than an interface.
44  *
45  * <p>The {@code Map} interface provides three <i>collection views</i>, which
46  * allow a map's contents to be viewed as a set of keys, collection of values,
47  * or set of key-value mappings.  The <i>order</i> of a map is defined as
48  * the order in which the iterators on the map's collection views return their
49  * elements.  Some map implementations, like the {@code TreeMap} class, make
50  * specific guarantees as to their order; others, like the {@code HashMap}
51  * class, do not.
52  *
53  * <p>Note: great care must be exercised if mutable objects are used as map
54  * keys.  The behavior of a map is not specified if the value of an object is
55  * changed in a manner that affects {@code equals} comparisons while the
56  * object is a key in the map.  A special case of this prohibition is that it
57  * is not permissible for a map to contain itself as a key.  While it is
58  * permissible for a map to contain itself as a value, extreme caution is
59  * advised: the {@code equals} and {@code hashCode} methods are no longer
60  * well defined on such a map.
61  *
62  * <p>All general-purpose map implementation classes should provide two
63  * "standard" constructors: a void (no arguments) constructor which creates an
64  * empty map, and a constructor with a single argument of type {@code Map},
65  * which creates a new map with the same key-value mappings as its argument.
66  * In effect, the latter constructor allows the user to copy any map,
67  * producing an equivalent map of the desired class.  There is no way to
68  * enforce this recommendation (as interfaces cannot contain constructors) but
69  * all of the general-purpose map implementations in the JDK comply.
70  *
71  * <p>The "destructive" methods contained in this interface, that is, the
72  * methods that modify the map on which they operate, are specified to throw
73  * {@code UnsupportedOperationException} if this map does not support the
74  * operation.  If this is the case, these methods may, but are not required
75  * to, throw an {@code UnsupportedOperationException} if the invocation would
76  * have no effect on the map.  For example, invoking the {@link #putAll(Map)}
77  * method on an unmodifiable map may, but is not required to, throw the
78  * exception if the map whose mappings are to be "superimposed" is empty.
79  *
80  * <p>Some map implementations have restrictions on the keys and values they
81  * may contain.  For example, some implementations prohibit null keys and
82  * values, and some have restrictions on the types of their keys.  Attempting
83  * to insert an ineligible key or value throws an unchecked exception,
84  * typically {@code NullPointerException} or {@code ClassCastException}.
85  * Attempting to query the presence of an ineligible key or value may throw an
86  * exception, or it may simply return false; some implementations will exhibit
87  * the former behavior and some will exhibit the latter.  More generally,
88  * attempting an operation on an ineligible key or value whose completion
89  * would not result in the insertion of an ineligible element into the map may
90  * throw an exception or it may succeed, at the option of the implementation.
91  * Such exceptions are marked as "optional" in the specification for this
92  * interface.
93  *
94  * <p>Many methods in Collections Framework interfaces are defined
95  * in terms of the {@link Object#equals(Object) equals} method.  For
96  * example, the specification for the {@link #containsKey(Object)
97  * containsKey(Object key)} method says: "returns {@code true} if and
98  * only if this map contains a mapping for a key {@code k} such that
99  * {@code (key==null ? k==null : key.equals(k))}." This specification should
100  * <i>not</i> be construed to imply that invoking {@code Map.containsKey}
101  * with a non-null argument {@code key} will cause {@code key.equals(k)} to
102  * be invoked for any key {@code k}.  Implementations are free to
103  * implement optimizations whereby the {@code equals} invocation is avoided,
104  * for example, by first comparing the hash codes of the two keys.  (The
105  * {@link Object#hashCode()} specification guarantees that two objects with
106  * unequal hash codes cannot be equal.)  More generally, implementations of
107  * the various Collections Framework interfaces are free to take advantage of
108  * the specified behavior of underlying {@link Object} methods wherever the
109  * implementor deems it appropriate.
110  *
111  * <p>Some map operations which perform recursive traversal of the map may fail
112  * with an exception for self-referential instances where the map directly or
113  * indirectly contains itself. This includes the {@code clone()},
114  * {@code equals()}, {@code hashCode()} and {@code toString()} methods.
115  * Implementations may optionally handle the self-referential scenario, however
116  * most current implementations do not do so.
117  *
118  * @param <K> the type of keys maintained by this map
119  * @param <V> the type of mapped values
120  *
121  * @author  Josh Bloch
122  * @see HashMap
123  * @see TreeMap
124  * @see Hashtable
125  * @see SortedMap
126  * @see Collection
127  * @see Set
128  * @since 1.2
129  */
130 public interface Map<K, V> {
131     // Query Operations
132 
133     /**
134      * Returns the number of key-value mappings in this map.  If the
135      * map contains more than {@code Integer.MAX_VALUE} elements, returns
136      * {@code Integer.MAX_VALUE}.
137      *
138      * @return the number of key-value mappings in this map
139      */
size()140     int size();
141 
142     /**
143      * Returns {@code true} if this map contains no key-value mappings.
144      *
145      * @return {@code true} if this map contains no key-value mappings
146      */
isEmpty()147     boolean isEmpty();
148 
149     /**
150      * Returns {@code true} if this map contains a mapping for the specified
151      * key.  More formally, returns {@code true} if and only if
152      * this map contains a mapping for a key {@code k} such that
153      * {@code Objects.equals(key, k)}.  (There can be
154      * at most one such mapping.)
155      *
156      * @param key key whose presence in this map is to be tested
157      * @return {@code true} if this map contains a mapping for the specified
158      *         key
159      * @throws ClassCastException if the key is of an inappropriate type for
160      *         this map
161      * (<a href="Collection.html#optional-restrictions">optional</a>)
162      * @throws NullPointerException if the specified key is null and this map
163      *         does not permit null keys
164      * (<a href="Collection.html#optional-restrictions">optional</a>)
165      */
containsKey(Object key)166     boolean containsKey(Object key);
167 
168     /**
169      * Returns {@code true} if this map maps one or more keys to the
170      * specified value.  More formally, returns {@code true} if and only if
171      * this map contains at least one mapping to a value {@code v} such that
172      * {@code Objects.equals(value, v)}.  This operation
173      * will probably require time linear in the map size for most
174      * implementations of the {@code Map} interface.
175      *
176      * @param value value whose presence in this map is to be tested
177      * @return {@code true} if this map maps one or more keys to the
178      *         specified value
179      * @throws ClassCastException if the value is of an inappropriate type for
180      *         this map
181      * (<a href="Collection.html#optional-restrictions">optional</a>)
182      * @throws NullPointerException if the specified value is null and this
183      *         map does not permit null values
184      * (<a href="Collection.html#optional-restrictions">optional</a>)
185      */
containsValue(Object value)186     boolean containsValue(Object value);
187 
188     /**
189      * Returns the value to which the specified key is mapped,
190      * or {@code null} if this map contains no mapping for the key.
191      *
192      * <p>More formally, if this map contains a mapping from a key
193      * {@code k} to a value {@code v} such that
194      * {@code Objects.equals(key, k)},
195      * then this method returns {@code v}; otherwise
196      * it returns {@code null}.  (There can be at most one such mapping.)
197      *
198      * <p>If this map permits null values, then a return value of
199      * {@code null} does not <i>necessarily</i> indicate that the map
200      * contains no mapping for the key; it's also possible that the map
201      * explicitly maps the key to {@code null}.  The {@link #containsKey
202      * containsKey} operation may be used to distinguish these two cases.
203      *
204      * @param key the key whose associated value is to be returned
205      * @return the value to which the specified key is mapped, or
206      *         {@code null} if this map contains no mapping for the key
207      * @throws ClassCastException if the key is of an inappropriate type for
208      *         this map
209      * (<a href="Collection.html#optional-restrictions">optional</a>)
210      * @throws NullPointerException if the specified key is null and this map
211      *         does not permit null keys
212      * (<a href="Collection.html#optional-restrictions">optional</a>)
213      */
get(Object key)214     V get(Object key);
215 
216     // Modification Operations
217 
218     /**
219      * Associates the specified value with the specified key in this map
220      * (optional operation).  If the map previously contained a mapping for
221      * the key, the old value is replaced by the specified value.  (A map
222      * {@code m} is said to contain a mapping for a key {@code k} if and only
223      * if {@link #containsKey(Object) m.containsKey(k)} would return
224      * {@code true}.)
225      *
226      * @param key key with which the specified value is to be associated
227      * @param value value to be associated with the specified key
228      * @return the previous value associated with {@code key}, or
229      *         {@code null} if there was no mapping for {@code key}.
230      *         (A {@code null} return can also indicate that the map
231      *         previously associated {@code null} with {@code key},
232      *         if the implementation supports {@code null} values.)
233      * @throws UnsupportedOperationException if the {@code put} operation
234      *         is not supported by this map
235      * @throws ClassCastException if the class of the specified key or value
236      *         prevents it from being stored in this map
237      * @throws NullPointerException if the specified key or value is null
238      *         and this map does not permit null keys or values
239      * @throws IllegalArgumentException if some property of the specified key
240      *         or value prevents it from being stored in this map
241      */
put(K key, V value)242     V put(K key, V value);
243 
244     /**
245      * Removes the mapping for a key from this map if it is present
246      * (optional operation).   More formally, if this map contains a mapping
247      * from key {@code k} to value {@code v} such that
248      * {@code Objects.equals(key, k)}, that mapping
249      * is removed.  (The map can contain at most one such mapping.)
250      *
251      * <p>Returns the value to which this map previously associated the key,
252      * or {@code null} if the map contained no mapping for the key.
253      *
254      * <p>If this map permits null values, then a return value of
255      * {@code null} does not <i>necessarily</i> indicate that the map
256      * contained no mapping for the key; it's also possible that the map
257      * explicitly mapped the key to {@code null}.
258      *
259      * <p>The map will not contain a mapping for the specified key once the
260      * call returns.
261      *
262      * @param key key whose mapping is to be removed from the map
263      * @return the previous value associated with {@code key}, or
264      *         {@code null} if there was no mapping for {@code key}.
265      * @throws UnsupportedOperationException if the {@code remove} operation
266      *         is not supported by this map
267      * @throws ClassCastException if the key is of an inappropriate type for
268      *         this map
269      * (<a href="Collection.html#optional-restrictions">optional</a>)
270      * @throws NullPointerException if the specified key is null and this
271      *         map does not permit null keys
272      * (<a href="Collection.html#optional-restrictions">optional</a>)
273      */
remove(Object key)274     V remove(Object key);
275 
276 
277     // Bulk Operations
278 
279     /**
280      * Copies all of the mappings from the specified map to this map
281      * (optional operation).  The effect of this call is equivalent to that
282      * of calling {@link #put(Object,Object) put(k, v)} on this map once
283      * for each mapping from key {@code k} to value {@code v} in the
284      * specified map.  The behavior of this operation is undefined if the
285      * specified map is modified while the operation is in progress.
286      *
287      * @param m mappings to be stored in this map
288      * @throws UnsupportedOperationException if the {@code putAll} operation
289      *         is not supported by this map
290      * @throws ClassCastException if the class of a key or value in the
291      *         specified map prevents it from being stored in this map
292      * @throws NullPointerException if the specified map is null, or if
293      *         this map does not permit null keys or values, and the
294      *         specified map contains null keys or values
295      * @throws IllegalArgumentException if some property of a key or value in
296      *         the specified map prevents it from being stored in this map
297      */
putAll(Map<? extends K, ? extends V> m)298     void putAll(Map<? extends K, ? extends V> m);
299 
300     /**
301      * Removes all of the mappings from this map (optional operation).
302      * The map will be empty after this call returns.
303      *
304      * @throws UnsupportedOperationException if the {@code clear} operation
305      *         is not supported by this map
306      */
clear()307     void clear();
308 
309 
310     // Views
311 
312     /**
313      * Returns a {@link Set} view of the keys contained in this map.
314      * The set is backed by the map, so changes to the map are
315      * reflected in the set, and vice-versa.  If the map is modified
316      * while an iteration over the set is in progress (except through
317      * the iterator's own {@code remove} operation), the results of
318      * the iteration are undefined.  The set supports element removal,
319      * which removes the corresponding mapping from the map, via the
320      * {@code Iterator.remove}, {@code Set.remove},
321      * {@code removeAll}, {@code retainAll}, and {@code clear}
322      * operations.  It does not support the {@code add} or {@code addAll}
323      * operations.
324      *
325      * @return a set view of the keys contained in this map
326      */
keySet()327     Set<K> keySet();
328 
329     /**
330      * Returns a {@link Collection} view of the values contained in this map.
331      * The collection is backed by the map, so changes to the map are
332      * reflected in the collection, and vice-versa.  If the map is
333      * modified while an iteration over the collection is in progress
334      * (except through the iterator's own {@code remove} operation),
335      * the results of the iteration are undefined.  The collection
336      * supports element removal, which removes the corresponding
337      * mapping from the map, via the {@code Iterator.remove},
338      * {@code Collection.remove}, {@code removeAll},
339      * {@code retainAll} and {@code clear} operations.  It does not
340      * support the {@code add} or {@code addAll} operations.
341      *
342      * @return a collection view of the values contained in this map
343      */
values()344     Collection<V> values();
345 
346     /**
347      * Returns a {@link Set} view of the mappings contained in this map.
348      * The set is backed by the map, so changes to the map are
349      * reflected in the set, and vice-versa.  If the map is modified
350      * while an iteration over the set is in progress (except through
351      * the iterator's own {@code remove} operation, or through the
352      * {@code setValue} operation on a map entry returned by the
353      * iterator) the results of the iteration are undefined.  The set
354      * supports element removal, which removes the corresponding
355      * mapping from the map, via the {@code Iterator.remove},
356      * {@code Set.remove}, {@code removeAll}, {@code retainAll} and
357      * {@code clear} operations.  It does not support the
358      * {@code add} or {@code addAll} operations.
359      *
360      * @return a set view of the mappings contained in this map
361      */
entrySet()362     Set<Map.Entry<K, V>> entrySet();
363 
364     /**
365      * A map entry (key-value pair).  The {@code Map.entrySet} method returns
366      * a collection-view of the map, whose elements are of this class.  The
367      * <i>only</i> way to obtain a reference to a map entry is from the
368      * iterator of this collection-view.  These {@code Map.Entry} objects are
369      * valid <i>only</i> for the duration of the iteration; more formally,
370      * the behavior of a map entry is undefined if the backing map has been
371      * modified after the entry was returned by the iterator, except through
372      * the {@code setValue} operation on the map entry.
373      *
374      * @see Map#entrySet()
375      * @since 1.2
376      */
377     interface Entry<K, V> {
378         /**
379          * Returns the key corresponding to this entry.
380          *
381          * @return the key corresponding to this entry
382          * @throws IllegalStateException implementations may, but are not
383          *         required to, throw this exception if the entry has been
384          *         removed from the backing map.
385          */
getKey()386         K getKey();
387 
388         /**
389          * Returns the value corresponding to this entry.  If the mapping
390          * has been removed from the backing map (by the iterator's
391          * {@code remove} operation), the results of this call are undefined.
392          *
393          * @return the value corresponding to this entry
394          * @throws IllegalStateException implementations may, but are not
395          *         required to, throw this exception if the entry has been
396          *         removed from the backing map.
397          */
getValue()398         V getValue();
399 
400         /**
401          * Replaces the value corresponding to this entry with the specified
402          * value (optional operation).  (Writes through to the map.)  The
403          * behavior of this call is undefined if the mapping has already been
404          * removed from the map (by the iterator's {@code remove} operation).
405          *
406          * @param value new value to be stored in this entry
407          * @return old value corresponding to the entry
408          * @throws UnsupportedOperationException if the {@code put} operation
409          *         is not supported by the backing map
410          * @throws ClassCastException if the class of the specified value
411          *         prevents it from being stored in the backing map
412          * @throws NullPointerException if the backing map does not permit
413          *         null values, and the specified value is null
414          * @throws IllegalArgumentException if some property of this value
415          *         prevents it from being stored in the backing map
416          * @throws IllegalStateException implementations may, but are not
417          *         required to, throw this exception if the entry has been
418          *         removed from the backing map.
419          */
setValue(V value)420         V setValue(V value);
421 
422         /**
423          * Compares the specified object with this entry for equality.
424          * Returns {@code true} if the given object is also a map entry and
425          * the two entries represent the same mapping.  More formally, two
426          * entries {@code e1} and {@code e2} represent the same mapping
427          * if<pre>
428          *     (e1.getKey()==null ?
429          *      e2.getKey()==null : e1.getKey().equals(e2.getKey()))  &amp;&amp;
430          *     (e1.getValue()==null ?
431          *      e2.getValue()==null : e1.getValue().equals(e2.getValue()))
432          * </pre>
433          * This ensures that the {@code equals} method works properly across
434          * different implementations of the {@code Map.Entry} interface.
435          *
436          * @param o object to be compared for equality with this map entry
437          * @return {@code true} if the specified object is equal to this map
438          *         entry
439          */
equals(Object o)440         boolean equals(Object o);
441 
442         /**
443          * Returns the hash code value for this map entry.  The hash code
444          * of a map entry {@code e} is defined to be: <pre>
445          *     (e.getKey()==null   ? 0 : e.getKey().hashCode()) ^
446          *     (e.getValue()==null ? 0 : e.getValue().hashCode())
447          * </pre>
448          * This ensures that {@code e1.equals(e2)} implies that
449          * {@code e1.hashCode()==e2.hashCode()} for any two Entries
450          * {@code e1} and {@code e2}, as required by the general
451          * contract of {@code Object.hashCode}.
452          *
453          * @return the hash code value for this map entry
454          * @see Object#hashCode()
455          * @see Object#equals(Object)
456          * @see #equals(Object)
457          */
hashCode()458         int hashCode();
459 
460         /**
461          * Returns a comparator that compares {@link Map.Entry} in natural order on key.
462          *
463          * <p>The returned comparator is serializable and throws {@link
464          * NullPointerException} when comparing an entry with a null key.
465          *
466          * @param  <K> the {@link Comparable} type of then map keys
467          * @param  <V> the type of the map values
468          * @return a comparator that compares {@link Map.Entry} in natural order on key.
469          * @see Comparable
470          * @since 1.8
471          */
comparingByKey()472         public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {
473             return (Comparator<Map.Entry<K, V>> & Serializable)
474                 (c1, c2) -> c1.getKey().compareTo(c2.getKey());
475         }
476 
477         /**
478          * Returns a comparator that compares {@link Map.Entry} in natural order on value.
479          *
480          * <p>The returned comparator is serializable and throws {@link
481          * NullPointerException} when comparing an entry with null values.
482          *
483          * @param <K> the type of the map keys
484          * @param <V> the {@link Comparable} type of the map values
485          * @return a comparator that compares {@link Map.Entry} in natural order on value.
486          * @see Comparable
487          * @since 1.8
488          */
comparingByValue()489         public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
490             return (Comparator<Map.Entry<K, V>> & Serializable)
491                 (c1, c2) -> c1.getValue().compareTo(c2.getValue());
492         }
493 
494         /**
495          * Returns a comparator that compares {@link Map.Entry} by key using the given
496          * {@link Comparator}.
497          *
498          * <p>The returned comparator is serializable if the specified comparator
499          * is also serializable.
500          *
501          * @param  <K> the type of the map keys
502          * @param  <V> the type of the map values
503          * @param  cmp the key {@link Comparator}
504          * @return a comparator that compares {@link Map.Entry} by the key.
505          * @since 1.8
506          */
comparingByKey(Comparator<? super K> cmp)507         public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
508             Objects.requireNonNull(cmp);
509             return (Comparator<Map.Entry<K, V>> & Serializable)
510                 (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
511         }
512 
513         /**
514          * Returns a comparator that compares {@link Map.Entry} by value using the given
515          * {@link Comparator}.
516          *
517          * <p>The returned comparator is serializable if the specified comparator
518          * is also serializable.
519          *
520          * @param  <K> the type of the map keys
521          * @param  <V> the type of the map values
522          * @param  cmp the value {@link Comparator}
523          * @return a comparator that compares {@link Map.Entry} by the value.
524          * @since 1.8
525          */
comparingByValue(Comparator<? super V> cmp)526         public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
527             Objects.requireNonNull(cmp);
528             return (Comparator<Map.Entry<K, V>> & Serializable)
529                 (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
530         }
531     }
532 
533     // Comparison and hashing
534 
535     /**
536      * Compares the specified object with this map for equality.  Returns
537      * {@code true} if the given object is also a map and the two maps
538      * represent the same mappings.  More formally, two maps {@code m1} and
539      * {@code m2} represent the same mappings if
540      * {@code m1.entrySet().equals(m2.entrySet())}.  This ensures that the
541      * {@code equals} method works properly across different implementations
542      * of the {@code Map} interface.
543      *
544      * @param o object to be compared for equality with this map
545      * @return {@code true} if the specified object is equal to this map
546      */
equals(Object o)547     boolean equals(Object o);
548 
549     /**
550      * Returns the hash code value for this map.  The hash code of a map is
551      * defined to be the sum of the hash codes of each entry in the map's
552      * {@code entrySet()} view.  This ensures that {@code m1.equals(m2)}
553      * implies that {@code m1.hashCode()==m2.hashCode()} for any two maps
554      * {@code m1} and {@code m2}, as required by the general contract of
555      * {@link Object#hashCode}.
556      *
557      * @return the hash code value for this map
558      * @see Map.Entry#hashCode()
559      * @see Object#equals(Object)
560      * @see #equals(Object)
561      */
hashCode()562     int hashCode();
563 
564     // Defaultable methods
565 
566     /**
567      * Returns the value to which the specified key is mapped, or
568      * {@code defaultValue} if this map contains no mapping for the key.
569      *
570      * @implSpec
571      * The default implementation makes no guarantees about synchronization
572      * or atomicity properties of this method. Any implementation providing
573      * atomicity guarantees must override this method and document its
574      * concurrency properties.
575      *
576      * @param key the key whose associated value is to be returned
577      * @param defaultValue the default mapping of the key
578      * @return the value to which the specified key is mapped, or
579      * {@code defaultValue} if this map contains no mapping for the key
580      * @throws ClassCastException if the key is of an inappropriate type for
581      * this map
582      * (<a href="Collection.html#optional-restrictions">optional</a>)
583      * @throws NullPointerException if the specified key is null and this map
584      * does not permit null keys
585      * (<a href="Collection.html#optional-restrictions">optional</a>)
586      * @since 1.8
587      */
getOrDefault(Object key, V defaultValue)588     default V getOrDefault(Object key, V defaultValue) {
589         V v;
590         return (((v = get(key)) != null) || containsKey(key))
591             ? v
592             : defaultValue;
593     }
594 
595     /**
596      * Performs the given action for each entry in this map until all entries
597      * have been processed or the action throws an exception.   Unless
598      * otherwise specified by the implementing class, actions are performed in
599      * the order of entry set iteration (if an iteration order is specified.)
600      * Exceptions thrown by the action are relayed to the caller.
601      *
602      * @implSpec
603      * The default implementation is equivalent to, for this {@code map}:
604      * <pre> {@code
605      * for (Map.Entry<K, V> entry : map.entrySet())
606      *     action.accept(entry.getKey(), entry.getValue());
607      * }</pre>
608      *
609      * The default implementation makes no guarantees about synchronization
610      * or atomicity properties of this method. Any implementation providing
611      * atomicity guarantees must override this method and document its
612      * concurrency properties.
613      *
614      * @param action The action to be performed for each entry
615      * @throws NullPointerException if the specified action is null
616      * @throws ConcurrentModificationException if an entry is found to be
617      * removed during iteration
618      * @since 1.8
619      */
forEach(BiConsumer<? super K, ? super V> action)620     default void forEach(BiConsumer<? super K, ? super V> action) {
621         Objects.requireNonNull(action);
622         for (Map.Entry<K, V> entry : entrySet()) {
623             K k;
624             V v;
625             try {
626                 k = entry.getKey();
627                 v = entry.getValue();
628             } catch (IllegalStateException ise) {
629                 // this usually means the entry is no longer in the map.
630                 throw new ConcurrentModificationException(ise);
631             }
632             action.accept(k, v);
633         }
634     }
635 
636     /**
637      * Replaces each entry's value with the result of invoking the given
638      * function on that entry until all entries have been processed or the
639      * function throws an exception.  Exceptions thrown by the function are
640      * relayed to the caller.
641      *
642      * @implSpec
643      * <p>The default implementation is equivalent to, for this {@code map}:
644      * <pre> {@code
645      * for (Map.Entry<K, V> entry : map.entrySet())
646      *     entry.setValue(function.apply(entry.getKey(), entry.getValue()));
647      * }</pre>
648      *
649      * <p>The default implementation makes no guarantees about synchronization
650      * or atomicity properties of this method. Any implementation providing
651      * atomicity guarantees must override this method and document its
652      * concurrency properties.
653      *
654      * @param function the function to apply to each entry
655      * @throws UnsupportedOperationException if the {@code set} operation
656      * is not supported by this map's entry set iterator.
657      * @throws ClassCastException if the class of a replacement value
658      * prevents it from being stored in this map
659      * @throws NullPointerException if the specified function is null, or the
660      * specified replacement value is null, and this map does not permit null
661      * values
662      * @throws ClassCastException if a replacement value is of an inappropriate
663      *         type for this map
664      *         (<a href="Collection.html#optional-restrictions">optional</a>)
665      * @throws NullPointerException if function or a replacement value is null,
666      *         and this map does not permit null keys or values
667      *         (<a href="Collection.html#optional-restrictions">optional</a>)
668      * @throws IllegalArgumentException if some property of a replacement value
669      *         prevents it from being stored in this map
670      *         (<a href="Collection.html#optional-restrictions">optional</a>)
671      * @throws ConcurrentModificationException if an entry is found to be
672      * removed during iteration
673      * @since 1.8
674      */
replaceAll(BiFunction<? super K, ? super V, ? extends V> function)675     default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
676         Objects.requireNonNull(function);
677         for (Map.Entry<K, V> entry : entrySet()) {
678             K k;
679             V v;
680             try {
681                 k = entry.getKey();
682                 v = entry.getValue();
683             } catch (IllegalStateException ise) {
684                 // this usually means the entry is no longer in the map.
685                 throw new ConcurrentModificationException(ise);
686             }
687 
688             // ise thrown from function is not a cme.
689             v = function.apply(k, v);
690 
691             try {
692                 entry.setValue(v);
693             } catch (IllegalStateException ise) {
694                 // this usually means the entry is no longer in the map.
695                 throw new ConcurrentModificationException(ise);
696             }
697         }
698     }
699 
700     /**
701      * If the specified key is not already associated with a value (or is mapped
702      * to {@code null}) associates it with the given value and returns
703      * {@code null}, else returns the current value.
704      *
705      * @implSpec
706      * The default implementation is equivalent to, for this {@code
707      * map}:
708      *
709      * <pre> {@code
710      * V v = map.get(key);
711      * if (v == null)
712      *     v = map.put(key, value);
713      *
714      * return v;
715      * }</pre>
716      *
717      * <p>The default implementation makes no guarantees about synchronization
718      * or atomicity properties of this method. Any implementation providing
719      * atomicity guarantees must override this method and document its
720      * concurrency properties.
721      *
722      * @param key key with which the specified value is to be associated
723      * @param value value to be associated with the specified key
724      * @return the previous value associated with the specified key, or
725      *         {@code null} if there was no mapping for the key.
726      *         (A {@code null} return can also indicate that the map
727      *         previously associated {@code null} with the key,
728      *         if the implementation supports null values.)
729      * @throws UnsupportedOperationException if the {@code put} operation
730      *         is not supported by this map
731      *         (<a href="Collection.html#optional-restrictions">optional</a>)
732      * @throws ClassCastException if the key or value is of an inappropriate
733      *         type for this map
734      *         (<a href="Collection.html#optional-restrictions">optional</a>)
735      * @throws NullPointerException if the specified key or value is null,
736      *         and this map does not permit null keys or values
737      *         (<a href="Collection.html#optional-restrictions">optional</a>)
738      * @throws IllegalArgumentException if some property of the specified key
739      *         or value prevents it from being stored in this map
740      *         (<a href="Collection.html#optional-restrictions">optional</a>)
741      * @since 1.8
742      */
putIfAbsent(K key, V value)743     default V putIfAbsent(K key, V value) {
744         V v = get(key);
745         if (v == null) {
746             v = put(key, value);
747         }
748 
749         return v;
750     }
751 
752     /**
753      * Removes the entry for the specified key only if it is currently
754      * mapped to the specified value.
755      *
756      * @implSpec
757      * The default implementation is equivalent to, for this {@code map}:
758      *
759      * <pre> {@code
760      * if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
761      *     map.remove(key);
762      *     return true;
763      * } else
764      *     return false;
765      * }</pre>
766      *
767      * <p>The default implementation makes no guarantees about synchronization
768      * or atomicity properties of this method. Any implementation providing
769      * atomicity guarantees must override this method and document its
770      * concurrency properties.
771      *
772      * @param key key with which the specified value is associated
773      * @param value value expected to be associated with the specified key
774      * @return {@code true} if the value was removed
775      * @throws UnsupportedOperationException if the {@code remove} operation
776      *         is not supported by this map
777      *         (<a href="Collection.html#optional-restrictions">optional</a>)
778      * @throws ClassCastException if the key or value is of an inappropriate
779      *         type for this map
780      *         (<a href="Collection.html#optional-restrictions">optional</a>)
781      * @throws NullPointerException if the specified key or value is null,
782      *         and this map does not permit null keys or values
783      *         (<a href="Collection.html#optional-restrictions">optional</a>)
784      * @since 1.8
785      */
remove(Object key, Object value)786     default boolean remove(Object key, Object value) {
787         Object curValue = get(key);
788         if (!Objects.equals(curValue, value) ||
789             (curValue == null && !containsKey(key))) {
790             return false;
791         }
792         remove(key);
793         return true;
794     }
795 
796     /**
797      * Replaces the entry for the specified key only if currently
798      * mapped to the specified value.
799      *
800      * @implSpec
801      * The default implementation is equivalent to, for this {@code map}:
802      *
803      * <pre> {@code
804      * if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
805      *     map.put(key, newValue);
806      *     return true;
807      * } else
808      *     return false;
809      * }</pre>
810      *
811      * The default implementation does not throw NullPointerException
812      * for maps that do not support null values if oldValue is null unless
813      * newValue is also null.
814      *
815      * <p>The default implementation makes no guarantees about synchronization
816      * or atomicity properties of this method. Any implementation providing
817      * atomicity guarantees must override this method and document its
818      * concurrency properties.
819      *
820      * @param key key with which the specified value is associated
821      * @param oldValue value expected to be associated with the specified key
822      * @param newValue value to be associated with the specified key
823      * @return {@code true} if the value was replaced
824      * @throws UnsupportedOperationException if the {@code put} operation
825      *         is not supported by this map
826      *         (<a href="Collection.html#optional-restrictions">optional</a>)
827      * @throws ClassCastException if the class of a specified key or value
828      *         prevents it from being stored in this map
829      * @throws NullPointerException if a specified key or newValue is null,
830      *         and this map does not permit null keys or values
831      * @throws NullPointerException if oldValue is null and this map does not
832      *         permit null values
833      *         (<a href="Collection.html#optional-restrictions">optional</a>)
834      * @throws IllegalArgumentException if some property of a specified key
835      *         or value prevents it from being stored in this map
836      * @since 1.8
837      */
replace(K key, V oldValue, V newValue)838     default boolean replace(K key, V oldValue, V newValue) {
839         Object curValue = get(key);
840         if (!Objects.equals(curValue, oldValue) ||
841             (curValue == null && !containsKey(key))) {
842             return false;
843         }
844         put(key, newValue);
845         return true;
846     }
847 
848     /**
849      * Replaces the entry for the specified key only if it is
850      * currently mapped to some value.
851      *
852      * @implSpec
853      * The default implementation is equivalent to, for this {@code map}:
854      *
855      * <pre> {@code
856      * if (map.containsKey(key)) {
857      *     return map.put(key, value);
858      * } else
859      *     return null;
860      * }</pre>
861      *
862      * <p>The default implementation makes no guarantees about synchronization
863      * or atomicity properties of this method. Any implementation providing
864      * atomicity guarantees must override this method and document its
865      * concurrency properties.
866      *
867      * @param key key with which the specified value is associated
868      * @param value value to be associated with the specified key
869      * @return the previous value associated with the specified key, or
870      *         {@code null} if there was no mapping for the key.
871      *         (A {@code null} return can also indicate that the map
872      *         previously associated {@code null} with the key,
873      *         if the implementation supports null values.)
874      * @throws UnsupportedOperationException if the {@code put} operation
875      *         is not supported by this map
876      *         (<a href="Collection.html#optional-restrictions">optional</a>)
877      * @throws ClassCastException if the class of the specified key or value
878      *         prevents it from being stored in this map
879      *         (<a href="Collection.html#optional-restrictions">optional</a>)
880      * @throws NullPointerException if the specified key or value is null,
881      *         and this map does not permit null keys or values
882      * @throws IllegalArgumentException if some property of the specified key
883      *         or value prevents it from being stored in this map
884      * @since 1.8
885      */
replace(K key, V value)886     default V replace(K key, V value) {
887         V curValue;
888         if (((curValue = get(key)) != null) || containsKey(key)) {
889             curValue = put(key, value);
890         }
891         return curValue;
892     }
893 
894     /**
895      * If the specified key is not already associated with a value (or is mapped
896      * to {@code null}), attempts to compute its value using the given mapping
897      * function and enters it into this map unless {@code null}.
898      *
899      * <p>If the mapping function returns {@code null}, no mapping is recorded.
900      * If the mapping function itself throws an (unchecked) exception, the
901      * exception is rethrown, and no mapping is recorded.  The most
902      * common usage is to construct a new object serving as an initial
903      * mapped value or memoized result, as in:
904      *
905      * <pre> {@code
906      * map.computeIfAbsent(key, k -> new Value(f(k)));
907      * }</pre>
908      *
909      * <p>Or to implement a multi-value map, {@code Map<K,Collection<V>>},
910      * supporting multiple values per key:
911      *
912      * <pre> {@code
913      * map.computeIfAbsent(key, k -> new HashSet<V>()).add(v);
914      * }</pre>
915      *
916      * <p>The mapping function should not modify this map during computation.
917      *
918      * @implSpec
919      * The default implementation is equivalent to the following steps for this
920      * {@code map}, then returning the current value or {@code null} if now
921      * absent:
922      *
923      * <pre> {@code
924      * if (map.get(key) == null) {
925      *     V newValue = mappingFunction.apply(key);
926      *     if (newValue != null)
927      *         map.put(key, newValue);
928      * }
929      * }</pre>
930      *
931      * <p>The default implementation makes no guarantees about detecting if the
932      * mapping function modifies this map during computation and, if
933      * appropriate, reporting an error. Non-concurrent implementations should
934      * override this method and, on a best-effort basis, throw a
935      * {@code ConcurrentModificationException} if it is detected that the
936      * mapping function modifies this map during computation. Concurrent
937      * implementations should override this method and, on a best-effort basis,
938      * throw an {@code IllegalStateException} if it is detected that the
939      * mapping function modifies this map during computation and as a result
940      * computation would never complete.
941      *
942      * <p>The default implementation makes no guarantees about synchronization
943      * or atomicity properties of this method. Any implementation providing
944      * atomicity guarantees must override this method and document its
945      * concurrency properties. In particular, all implementations of
946      * subinterface {@link java.util.concurrent.ConcurrentMap} must document
947      * whether the mapping function is applied once atomically only if the value
948      * is not present.
949      *
950      * @param key key with which the specified value is to be associated
951      * @param mappingFunction the mapping function to compute a value
952      * @return the current (existing or computed) value associated with
953      *         the specified key, or null if the computed value is null
954      * @throws NullPointerException if the specified key is null and
955      *         this map does not support null keys, or the mappingFunction
956      *         is null
957      * @throws UnsupportedOperationException if the {@code put} operation
958      *         is not supported by this map
959      *         (<a href="Collection.html#optional-restrictions">optional</a>)
960      * @throws ClassCastException if the class of the specified key or value
961      *         prevents it from being stored in this map
962      *         (<a href="Collection.html#optional-restrictions">optional</a>)
963      * @throws IllegalArgumentException if some property of the specified key
964      *         or value prevents it from being stored in this map
965      *         (<a href="Collection.html#optional-restrictions">optional</a>)
966      * @since 1.8
967      */
computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)968     default V computeIfAbsent(K key,
969             Function<? super K, ? extends V> mappingFunction) {
970         Objects.requireNonNull(mappingFunction);
971         V v;
972         if ((v = get(key)) == null) {
973             V newValue;
974             if ((newValue = mappingFunction.apply(key)) != null) {
975                 put(key, newValue);
976                 return newValue;
977             }
978         }
979 
980         return v;
981     }
982 
983     /**
984      * If the value for the specified key is present and non-null, attempts to
985      * compute a new mapping given the key and its current mapped value.
986      *
987      * <p>If the remapping function returns {@code null}, the mapping is removed.
988      * If the remapping function itself throws an (unchecked) exception, the
989      * exception is rethrown, and the current mapping is left unchanged.
990      *
991      * <p>The remapping function should not modify this map during computation.
992      *
993      * @implSpec
994      * The default implementation is equivalent to performing the following
995      * steps for this {@code map}, then returning the current value or
996      * {@code null} if now absent:
997      *
998      * <pre> {@code
999      * if (map.get(key) != null) {
1000      *     V oldValue = map.get(key);
1001      *     V newValue = remappingFunction.apply(key, oldValue);
1002      *     if (newValue != null)
1003      *         map.put(key, newValue);
1004      *     else
1005      *         map.remove(key);
1006      * }
1007      * }</pre>
1008      *
1009      * <p>The default implementation makes no guarantees about detecting if the
1010      * remapping function modifies this map during computation and, if
1011      * appropriate, reporting an error. Non-concurrent implementations should
1012      * override this method and, on a best-effort basis, throw a
1013      * {@code ConcurrentModificationException} if it is detected that the
1014      * remapping function modifies this map during computation. Concurrent
1015      * implementations should override this method and, on a best-effort basis,
1016      * throw an {@code IllegalStateException} if it is detected that the
1017      * remapping function modifies this map during computation and as a result
1018      * computation would never complete.
1019      *
1020      * <p>The default implementation makes no guarantees about synchronization
1021      * or atomicity properties of this method. Any implementation providing
1022      * atomicity guarantees must override this method and document its
1023      * concurrency properties. In particular, all implementations of
1024      * subinterface {@link java.util.concurrent.ConcurrentMap} must document
1025      * whether the remapping function is applied once atomically only if the
1026      * value is not present.
1027      *
1028      * @param key key with which the specified value is to be associated
1029      * @param remappingFunction the remapping function to compute a value
1030      * @return the new value associated with the specified key, or null if none
1031      * @throws NullPointerException if the specified key is null and
1032      *         this map does not support null keys, or the
1033      *         remappingFunction is null
1034      * @throws UnsupportedOperationException if the {@code put} operation
1035      *         is not supported by this map
1036      *         (<a href="Collection.html#optional-restrictions">optional</a>)
1037      * @throws ClassCastException if the class of the specified key or value
1038      *         prevents it from being stored in this map
1039      *         (<a href="Collection.html#optional-restrictions">optional</a>)
1040      * @throws IllegalArgumentException if some property of the specified key
1041      *         or value prevents it from being stored in this map
1042      *         (<a href="Collection.html#optional-restrictions">optional</a>)
1043      * @since 1.8
1044      */
computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)1045     default V computeIfPresent(K key,
1046             BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1047         Objects.requireNonNull(remappingFunction);
1048         V oldValue;
1049         if ((oldValue = get(key)) != null) {
1050             V newValue = remappingFunction.apply(key, oldValue);
1051             if (newValue != null) {
1052                 put(key, newValue);
1053                 return newValue;
1054             } else {
1055                 remove(key);
1056                 return null;
1057             }
1058         } else {
1059             return null;
1060         }
1061     }
1062 
1063     /**
1064      * Attempts to compute a mapping for the specified key and its current
1065      * mapped value (or {@code null} if there is no current mapping). For
1066      * example, to either create or append a {@code String} msg to a value
1067      * mapping:
1068      *
1069      * <pre> {@code
1070      * map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre>
1071      * (Method {@link #merge merge()} is often simpler to use for such purposes.)
1072      *
1073      * <p>If the remapping function returns {@code null}, the mapping is removed
1074      * (or remains absent if initially absent).  If the remapping function
1075      * itself throws an (unchecked) exception, the exception is rethrown, and
1076      * the current mapping is left unchanged.
1077      *
1078      * <p>The remapping function should not modify this map during computation.
1079      *
1080      * @implSpec
1081      * The default implementation is equivalent to performing the following
1082      * steps for this {@code map}, then returning the current value or
1083      * {@code null} if absent:
1084      *
1085      * <pre> {@code
1086      * V oldValue = map.get(key);
1087      * V newValue = remappingFunction.apply(key, oldValue);
1088      * if (oldValue != null) {
1089      *    if (newValue != null)
1090      *       map.put(key, newValue);
1091      *    else
1092      *       map.remove(key);
1093      * } else {
1094      *    if (newValue != null)
1095      *       map.put(key, newValue);
1096      *    else
1097      *       return null;
1098      * }
1099      * }</pre>
1100      *
1101      * <p>The default implementation makes no guarantees about detecting if the
1102      * remapping function modifies this map during computation and, if
1103      * appropriate, reporting an error. Non-concurrent implementations should
1104      * override this method and, on a best-effort basis, throw a
1105      * {@code ConcurrentModificationException} if it is detected that the
1106      * remapping function modifies this map during computation. Concurrent
1107      * implementations should override this method and, on a best-effort basis,
1108      * throw an {@code IllegalStateException} if it is detected that the
1109      * remapping function modifies this map during computation and as a result
1110      * computation would never complete.
1111      *
1112      * <p>The default implementation makes no guarantees about synchronization
1113      * or atomicity properties of this method. Any implementation providing
1114      * atomicity guarantees must override this method and document its
1115      * concurrency properties. In particular, all implementations of
1116      * subinterface {@link java.util.concurrent.ConcurrentMap} must document
1117      * whether the remapping function is applied once atomically only if the
1118      * value is not present.
1119      *
1120      * @param key key with which the specified value is to be associated
1121      * @param remappingFunction the remapping function to compute a value
1122      * @return the new value associated with the specified key, or null if none
1123      * @throws NullPointerException if the specified key is null and
1124      *         this map does not support null keys, or the
1125      *         remappingFunction is null
1126      * @throws UnsupportedOperationException if the {@code put} operation
1127      *         is not supported by this map
1128      *         (<a href="Collection.html#optional-restrictions">optional</a>)
1129      * @throws ClassCastException if the class of the specified key or value
1130      *         prevents it from being stored in this map
1131      *         (<a href="Collection.html#optional-restrictions">optional</a>)
1132      * @throws IllegalArgumentException if some property of the specified key
1133      *         or value prevents it from being stored in this map
1134      *         (<a href="Collection.html#optional-restrictions">optional</a>)
1135      * @since 1.8
1136      */
compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)1137     default V compute(K key,
1138             BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1139         Objects.requireNonNull(remappingFunction);
1140         V oldValue = get(key);
1141 
1142         V newValue = remappingFunction.apply(key, oldValue);
1143         if (newValue == null) {
1144             // delete mapping
1145             if (oldValue != null || containsKey(key)) {
1146                 // something to remove
1147                 remove(key);
1148                 return null;
1149             } else {
1150                 // nothing to do. Leave things as they were.
1151                 return null;
1152             }
1153         } else {
1154             // add or replace old mapping
1155             put(key, newValue);
1156             return newValue;
1157         }
1158     }
1159 
1160     /**
1161      * If the specified key is not already associated with a value or is
1162      * associated with null, associates it with the given non-null value.
1163      * Otherwise, replaces the associated value with the results of the given
1164      * remapping function, or removes if the result is {@code null}. This
1165      * method may be of use when combining multiple mapped values for a key.
1166      * For example, to either create or append a {@code String msg} to a
1167      * value mapping:
1168      *
1169      * <pre> {@code
1170      * map.merge(key, msg, String::concat)
1171      * }</pre>
1172      *
1173      * <p>If the remapping function returns {@code null}, the mapping is removed.
1174      * If the remapping function itself throws an (unchecked) exception, the
1175      * exception is rethrown, and the current mapping is left unchanged.
1176      *
1177      * <p>The remapping function should not modify this map during computation.
1178      *
1179      * @implSpec
1180      * The default implementation is equivalent to performing the following
1181      * steps for this {@code map}, then returning the current value or
1182      * {@code null} if absent:
1183      *
1184      * <pre> {@code
1185      * V oldValue = map.get(key);
1186      * V newValue = (oldValue == null) ? value :
1187      *              remappingFunction.apply(oldValue, value);
1188      * if (newValue == null)
1189      *     map.remove(key);
1190      * else
1191      *     map.put(key, newValue);
1192      * }</pre>
1193      *
1194      * <p>The default implementation makes no guarantees about detecting if the
1195      * remapping function modifies this map during computation and, if
1196      * appropriate, reporting an error. Non-concurrent implementations should
1197      * override this method and, on a best-effort basis, throw a
1198      * {@code ConcurrentModificationException} if it is detected that the
1199      * remapping function modifies this map during computation. Concurrent
1200      * implementations should override this method and, on a best-effort basis,
1201      * throw an {@code IllegalStateException} if it is detected that the
1202      * remapping function modifies this map during computation and as a result
1203      * computation would never complete.
1204      *
1205      * <p>The default implementation makes no guarantees about synchronization
1206      * or atomicity properties of this method. Any implementation providing
1207      * atomicity guarantees must override this method and document its
1208      * concurrency properties. In particular, all implementations of
1209      * subinterface {@link java.util.concurrent.ConcurrentMap} must document
1210      * whether the remapping function is applied once atomically only if the
1211      * value is not present.
1212      *
1213      * @param key key with which the resulting value is to be associated
1214      * @param value the non-null value to be merged with the existing value
1215      *        associated with the key or, if no existing value or a null value
1216      *        is associated with the key, to be associated with the key
1217      * @param remappingFunction the remapping function to recompute a value if
1218      *        present
1219      * @return the new value associated with the specified key, or null if no
1220      *         value is associated with the key
1221      * @throws UnsupportedOperationException if the {@code put} operation
1222      *         is not supported by this map
1223      *         (<a href="Collection.html#optional-restrictions">optional</a>)
1224      * @throws ClassCastException if the class of the specified key or value
1225      *         prevents it from being stored in this map
1226      *         (<a href="Collection.html#optional-restrictions">optional</a>)
1227      * @throws IllegalArgumentException if some property of the specified key
1228      *         or value prevents it from being stored in this map
1229      *         (<a href="Collection.html#optional-restrictions">optional</a>)
1230      * @throws NullPointerException if the specified key is null and this map
1231      *         does not support null keys or the value or remappingFunction is
1232      *         null
1233      * @since 1.8
1234      */
merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)1235     default V merge(K key, V value,
1236             BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
1237         Objects.requireNonNull(remappingFunction);
1238         Objects.requireNonNull(value);
1239         V oldValue = get(key);
1240         V newValue = (oldValue == null) ? value :
1241                    remappingFunction.apply(oldValue, value);
1242         if (newValue == null) {
1243             remove(key);
1244         } else {
1245             put(key, newValue);
1246         }
1247         return newValue;
1248     }
1249 }
1250