ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Map.java
Revision: 1.4
Committed: Sat Mar 26 19:25:33 2016 UTC (8 years, 1 month ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +0 -0 lines
State: FILE REMOVED
Log Message:
drop local copies of Map.java and KeyValueHolder.java

File Contents

# User Rev Content
1 jsr166 1.1 /*
2 jsr166 1.3 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
3 jsr166 1.1 * 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     /**
34     * An object that maps keys to values. A map cannot contain duplicate keys;
35     * each key can map to at most one value.
36     *
37     * <p>This interface takes the place of the {@code Dictionary} class, which
38     * was a totally abstract class rather than an interface.
39     *
40     * <p>The {@code Map} interface provides three <i>collection views</i>, which
41     * allow a map's contents to be viewed as a set of keys, collection of values,
42     * or set of key-value mappings. The <i>order</i> of a map is defined as
43     * the order in which the iterators on the map's collection views return their
44     * elements. Some map implementations, like the {@code TreeMap} class, make
45     * specific guarantees as to their order; others, like the {@code HashMap}
46     * class, do not.
47     *
48     * <p>Note: great care must be exercised if mutable objects are used as map
49     * keys. The behavior of a map is not specified if the value of an object is
50     * changed in a manner that affects {@code equals} comparisons while the
51     * object is a key in the map. A special case of this prohibition is that it
52     * is not permissible for a map to contain itself as a key. While it is
53     * permissible for a map to contain itself as a value, extreme caution is
54     * advised: the {@code equals} and {@code hashCode} methods are no longer
55     * well defined on such a map.
56     *
57     * <p>All general-purpose map implementation classes should provide two
58     * "standard" constructors: a void (no arguments) constructor which creates an
59     * empty map, and a constructor with a single argument of type {@code Map},
60     * which creates a new map with the same key-value mappings as its argument.
61     * In effect, the latter constructor allows the user to copy any map,
62     * producing an equivalent map of the desired class. There is no way to
63     * enforce this recommendation (as interfaces cannot contain constructors) but
64     * all of the general-purpose map implementations in the JDK comply.
65     *
66     * <p>The "destructive" methods contained in this interface, that is, the
67     * methods that modify the map on which they operate, are specified to throw
68     * {@code UnsupportedOperationException} if this map does not support the
69     * operation. If this is the case, these methods may, but are not required
70     * to, throw an {@code UnsupportedOperationException} if the invocation would
71     * have no effect on the map. For example, invoking the {@link #putAll(Map)}
72     * method on an unmodifiable map may, but is not required to, throw the
73     * exception if the map whose mappings are to be "superimposed" is empty.
74     *
75     * <p>Some map implementations have restrictions on the keys and values they
76     * may contain. For example, some implementations prohibit null keys and
77     * values, and some have restrictions on the types of their keys. Attempting
78     * to insert an ineligible key or value throws an unchecked exception,
79     * typically {@code NullPointerException} or {@code ClassCastException}.
80     * Attempting to query the presence of an ineligible key or value may throw an
81     * exception, or it may simply return false; some implementations will exhibit
82     * the former behavior and some will exhibit the latter. More generally,
83     * attempting an operation on an ineligible key or value whose completion
84     * would not result in the insertion of an ineligible element into the map may
85     * throw an exception or it may succeed, at the option of the implementation.
86     * Such exceptions are marked as "optional" in the specification for this
87     * interface.
88     *
89     * <p>Many methods in Collections Framework interfaces are defined
90     * in terms of the {@link Object#equals(Object) equals} method. For
91     * example, the specification for the {@link #containsKey(Object)
92     * containsKey(Object key)} method says: "returns {@code true} if and
93     * only if this map contains a mapping for a key {@code k} such that
94     * {@code (key==null ? k==null : key.equals(k))}." This specification should
95     * <i>not</i> be construed to imply that invoking {@code Map.containsKey}
96     * with a non-null argument {@code key} will cause {@code key.equals(k)} to
97     * be invoked for any key {@code k}. Implementations are free to
98     * implement optimizations whereby the {@code equals} invocation is avoided,
99     * for example, by first comparing the hash codes of the two keys. (The
100     * {@link Object#hashCode()} specification guarantees that two objects with
101     * unequal hash codes cannot be equal.) More generally, implementations of
102     * the various Collections Framework interfaces are free to take advantage of
103     * the specified behavior of underlying {@link Object} methods wherever the
104     * implementor deems it appropriate.
105     *
106     * <p>Some map operations which perform recursive traversal of the map may fail
107     * with an exception for self-referential instances where the map directly or
108     * indirectly contains itself. This includes the {@code clone()},
109     * {@code equals()}, {@code hashCode()} and {@code toString()} methods.
110     * Implementations may optionally handle the self-referential scenario, however
111     * most current implementations do not do so.
112     *
113 jsr166 1.3 * <h2><a name="immutable">Immutable Map Static Factory Methods</a></h2>
114     * <p>The {@link Map#of() Map.of()} and
115     * {@link Map#ofEntries(Map.Entry...) Map.ofEntries()}
116     * static factory methods provide a convenient way to create immutable maps.
117     * The {@code Map}
118     * instances created by these methods have the following characteristics:
119     *
120     * <ul>
121     * <li>They are <em>structurally immutable</em>. Keys and values cannot be added,
122     * removed, or updated. Attempts to do so result in {@code UnsupportedOperationException}.
123     * However, if the contained keys or values are themselves mutable, this may cause the
124     * Map to behave inconsistently or its contents to appear to change.
125     * <li>They disallow {@code null} keys and values. Attempts to create them with
126     * {@code null} keys or values result in {@code NullPointerException}.
127     * <li>They are serializable if all keys and values are serializable.
128     * <li>They reject duplicate keys at creation time. Duplicate keys
129     * passed to a static factory method result in {@code IllegalArgumentException}.
130     * <li>The iteration order of mappings is unspecified and is subject to change.
131     * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
132     * Callers should make no assumptions about the identity of the returned instances.
133     * Factories are free to create new instances or reuse existing ones. Therefore,
134     * identity-sensitive operations on these instances (reference equality ({@code ==}),
135     * identity hash code, and synchronization) are unreliable and should be avoided.
136     * </ul>
137     *
138 jsr166 1.1 * <p>This interface is a member of the
139     * <a href="{@docRoot}/../technotes/guides/collections/index.html">
140     * Java Collections Framework</a>.
141     *
142     * @param <K> the type of keys maintained by this map
143     * @param <V> the type of mapped values
144     *
145     * @author Josh Bloch
146     * @see HashMap
147     * @see TreeMap
148     * @see Hashtable
149     * @see SortedMap
150     * @see Collection
151     * @see Set
152     * @since 1.2
153     */
154 jsr166 1.3 public interface Map<K, V> {
155 jsr166 1.1 // Query Operations
156    
157     /**
158     * Returns the number of key-value mappings in this map. If the
159     * map contains more than {@code Integer.MAX_VALUE} elements, returns
160     * {@code Integer.MAX_VALUE}.
161     *
162     * @return the number of key-value mappings in this map
163     */
164     int size();
165    
166     /**
167     * Returns {@code true} if this map contains no key-value mappings.
168     *
169     * @return {@code true} if this map contains no key-value mappings
170     */
171     boolean isEmpty();
172    
173     /**
174     * Returns {@code true} if this map contains a mapping for the specified
175     * key. More formally, returns {@code true} if and only if
176     * this map contains a mapping for a key {@code k} such that
177     * {@code Objects.equals(key, k)}. (There can be
178     * at most one such mapping.)
179     *
180     * @param key key whose presence in this map is to be tested
181     * @return {@code true} if this map contains a mapping for the specified
182     * key
183     * @throws ClassCastException if the key is of an inappropriate type for
184     * this map
185 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
186 jsr166 1.1 * @throws NullPointerException if the specified key is null and this map
187     * does not permit null keys
188 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
189 jsr166 1.1 */
190     boolean containsKey(Object key);
191    
192     /**
193     * Returns {@code true} if this map maps one or more keys to the
194     * specified value. More formally, returns {@code true} if and only if
195     * this map contains at least one mapping to a value {@code v} such that
196     * {@code Objects.equals(value, v)}. This operation
197     * will probably require time linear in the map size for most
198     * implementations of the {@code Map} interface.
199     *
200     * @param value value whose presence in this map is to be tested
201     * @return {@code true} if this map maps one or more keys to the
202     * specified value
203     * @throws ClassCastException if the value is of an inappropriate type for
204     * this map
205 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
206 jsr166 1.1 * @throws NullPointerException if the specified value is null and this
207     * map does not permit null values
208 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
209 jsr166 1.1 */
210     boolean containsValue(Object value);
211    
212     /**
213     * Returns the value to which the specified key is mapped,
214     * or {@code null} if this map contains no mapping for the key.
215     *
216     * <p>More formally, if this map contains a mapping from a key
217     * {@code k} to a value {@code v} such that
218     * {@code Objects.equals(key, k)},
219     * then this method returns {@code v}; otherwise
220     * it returns {@code null}. (There can be at most one such mapping.)
221     *
222     * <p>If this map permits null values, then a return value of
223     * {@code null} does not <i>necessarily</i> indicate that the map
224     * contains no mapping for the key; it's also possible that the map
225     * explicitly maps the key to {@code null}. The {@link #containsKey
226     * containsKey} operation may be used to distinguish these two cases.
227     *
228     * @param key the key whose associated value is to be returned
229     * @return the value to which the specified key is mapped, or
230     * {@code null} if this map contains no mapping for the key
231     * @throws ClassCastException if the key is of an inappropriate type for
232     * this map
233 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
234 jsr166 1.1 * @throws NullPointerException if the specified key is null and this map
235     * does not permit null keys
236 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
237 jsr166 1.1 */
238     V get(Object key);
239    
240     // Modification Operations
241    
242     /**
243     * Associates the specified value with the specified key in this map
244     * (optional operation). If the map previously contained a mapping for
245     * the key, the old value is replaced by the specified value. (A map
246     * {@code m} is said to contain a mapping for a key {@code k} if and only
247     * if {@link #containsKey(Object) m.containsKey(k)} would return
248     * {@code true}.)
249     *
250     * @param key key with which the specified value is to be associated
251     * @param value value to be associated with the specified key
252     * @return the previous value associated with {@code key}, or
253     * {@code null} if there was no mapping for {@code key}.
254     * (A {@code null} return can also indicate that the map
255     * previously associated {@code null} with {@code key},
256     * if the implementation supports {@code null} values.)
257     * @throws UnsupportedOperationException if the {@code put} operation
258     * is not supported by this map
259     * @throws ClassCastException if the class of the specified key or value
260     * prevents it from being stored in this map
261     * @throws NullPointerException if the specified key or value is null
262     * and this map does not permit null keys or values
263     * @throws IllegalArgumentException if some property of the specified key
264     * or value prevents it from being stored in this map
265     */
266     V put(K key, V value);
267    
268     /**
269     * Removes the mapping for a key from this map if it is present
270     * (optional operation). More formally, if this map contains a mapping
271     * from key {@code k} to value {@code v} such that
272     * {@code Objects.equals(key, k)}, that mapping
273     * is removed. (The map can contain at most one such mapping.)
274     *
275     * <p>Returns the value to which this map previously associated the key,
276     * or {@code null} if the map contained no mapping for the key.
277     *
278     * <p>If this map permits null values, then a return value of
279     * {@code null} does not <i>necessarily</i> indicate that the map
280     * contained no mapping for the key; it's also possible that the map
281     * explicitly mapped the key to {@code null}.
282     *
283     * <p>The map will not contain a mapping for the specified key once the
284     * call returns.
285     *
286     * @param key key whose mapping is to be removed from the map
287     * @return the previous value associated with {@code key}, or
288     * {@code null} if there was no mapping for {@code key}.
289     * @throws UnsupportedOperationException if the {@code remove} operation
290     * is not supported by this map
291     * @throws ClassCastException if the key is of an inappropriate type for
292     * this map
293 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
294 jsr166 1.1 * @throws NullPointerException if the specified key is null and this
295     * map does not permit null keys
296 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
297 jsr166 1.1 */
298     V remove(Object key);
299    
300    
301     // Bulk Operations
302    
303     /**
304     * Copies all of the mappings from the specified map to this map
305     * (optional operation). The effect of this call is equivalent to that
306     * of calling {@link #put(Object,Object) put(k, v)} on this map once
307     * for each mapping from key {@code k} to value {@code v} in the
308     * specified map. The behavior of this operation is undefined if the
309     * specified map is modified while the operation is in progress.
310     *
311     * @param m mappings to be stored in this map
312     * @throws UnsupportedOperationException if the {@code putAll} operation
313     * is not supported by this map
314     * @throws ClassCastException if the class of a key or value in the
315     * specified map prevents it from being stored in this map
316     * @throws NullPointerException if the specified map is null, or if
317     * this map does not permit null keys or values, and the
318     * specified map contains null keys or values
319     * @throws IllegalArgumentException if some property of a key or value in
320     * the specified map prevents it from being stored in this map
321     */
322     void putAll(Map<? extends K, ? extends V> m);
323    
324     /**
325     * Removes all of the mappings from this map (optional operation).
326     * The map will be empty after this call returns.
327     *
328     * @throws UnsupportedOperationException if the {@code clear} operation
329     * is not supported by this map
330     */
331     void clear();
332    
333    
334     // Views
335    
336     /**
337     * Returns a {@link Set} view of the keys contained in this map.
338     * The set is backed by the map, so changes to the map are
339     * reflected in the set, and vice-versa. If the map is modified
340     * while an iteration over the set is in progress (except through
341     * the iterator's own {@code remove} operation), the results of
342     * the iteration are undefined. The set supports element removal,
343     * which removes the corresponding mapping from the map, via the
344     * {@code Iterator.remove}, {@code Set.remove},
345     * {@code removeAll}, {@code retainAll}, and {@code clear}
346     * operations. It does not support the {@code add} or {@code addAll}
347     * operations.
348     *
349     * @return a set view of the keys contained in this map
350     */
351     Set<K> keySet();
352    
353     /**
354     * Returns a {@link Collection} view of the values contained in this map.
355     * The collection is backed by the map, so changes to the map are
356     * reflected in the collection, and vice-versa. If the map is
357     * modified while an iteration over the collection is in progress
358     * (except through the iterator's own {@code remove} operation),
359     * the results of the iteration are undefined. The collection
360     * supports element removal, which removes the corresponding
361     * mapping from the map, via the {@code Iterator.remove},
362     * {@code Collection.remove}, {@code removeAll},
363     * {@code retainAll} and {@code clear} operations. It does not
364     * support the {@code add} or {@code addAll} operations.
365     *
366     * @return a collection view of the values contained in this map
367     */
368     Collection<V> values();
369    
370     /**
371     * Returns a {@link Set} view of the mappings contained in this map.
372     * The set is backed by the map, so changes to the map are
373     * reflected in the set, and vice-versa. If the map is modified
374     * while an iteration over the set is in progress (except through
375     * the iterator's own {@code remove} operation, or through the
376     * {@code setValue} operation on a map entry returned by the
377     * iterator) the results of the iteration are undefined. The set
378     * supports element removal, which removes the corresponding
379     * mapping from the map, via the {@code Iterator.remove},
380     * {@code Set.remove}, {@code removeAll}, {@code retainAll} and
381     * {@code clear} operations. It does not support the
382     * {@code add} or {@code addAll} operations.
383     *
384     * @return a set view of the mappings contained in this map
385     */
386     Set<Map.Entry<K, V>> entrySet();
387    
388     /**
389     * A map entry (key-value pair). The {@code Map.entrySet} method returns
390     * a collection-view of the map, whose elements are of this class. The
391     * <i>only</i> way to obtain a reference to a map entry is from the
392     * iterator of this collection-view. These {@code Map.Entry} objects are
393     * valid <i>only</i> for the duration of the iteration; more formally,
394     * the behavior of a map entry is undefined if the backing map has been
395     * modified after the entry was returned by the iterator, except through
396     * the {@code setValue} operation on the map entry.
397     *
398     * @see Map#entrySet()
399     * @since 1.2
400     */
401 jsr166 1.3 interface Entry<K, V> {
402 jsr166 1.1 /**
403     * Returns the key corresponding to this entry.
404     *
405     * @return the key corresponding to this entry
406     * @throws IllegalStateException implementations may, but are not
407     * required to, throw this exception if the entry has been
408     * removed from the backing map.
409     */
410     K getKey();
411    
412     /**
413     * Returns the value corresponding to this entry. If the mapping
414     * has been removed from the backing map (by the iterator's
415     * {@code remove} operation), the results of this call are undefined.
416     *
417     * @return the value corresponding to this entry
418     * @throws IllegalStateException implementations may, but are not
419     * required to, throw this exception if the entry has been
420     * removed from the backing map.
421     */
422     V getValue();
423    
424     /**
425     * Replaces the value corresponding to this entry with the specified
426     * value (optional operation). (Writes through to the map.) The
427     * behavior of this call is undefined if the mapping has already been
428     * removed from the map (by the iterator's {@code remove} operation).
429     *
430     * @param value new value to be stored in this entry
431     * @return old value corresponding to the entry
432     * @throws UnsupportedOperationException if the {@code put} operation
433     * is not supported by the backing map
434     * @throws ClassCastException if the class of the specified value
435     * prevents it from being stored in the backing map
436     * @throws NullPointerException if the backing map does not permit
437     * null values, and the specified value is null
438     * @throws IllegalArgumentException if some property of this value
439     * prevents it from being stored in the backing map
440     * @throws IllegalStateException implementations may, but are not
441     * required to, throw this exception if the entry has been
442     * removed from the backing map.
443     */
444     V setValue(V value);
445    
446     /**
447     * Compares the specified object with this entry for equality.
448     * Returns {@code true} if the given object is also a map entry and
449     * the two entries represent the same mapping. More formally, two
450     * entries {@code e1} and {@code e2} represent the same mapping
451     * if<pre>
452     * (e1.getKey()==null ?
453     * e2.getKey()==null : e1.getKey().equals(e2.getKey())) &amp;&amp;
454     * (e1.getValue()==null ?
455     * e2.getValue()==null : e1.getValue().equals(e2.getValue()))
456     * </pre>
457     * This ensures that the {@code equals} method works properly across
458     * different implementations of the {@code Map.Entry} interface.
459     *
460     * @param o object to be compared for equality with this map entry
461     * @return {@code true} if the specified object is equal to this map
462     * entry
463     */
464     boolean equals(Object o);
465    
466     /**
467     * Returns the hash code value for this map entry. The hash code
468     * of a map entry {@code e} is defined to be: <pre>
469     * (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
470     * (e.getValue()==null ? 0 : e.getValue().hashCode())
471     * </pre>
472     * This ensures that {@code e1.equals(e2)} implies that
473     * {@code e1.hashCode()==e2.hashCode()} for any two Entries
474     * {@code e1} and {@code e2}, as required by the general
475     * contract of {@code Object.hashCode}.
476     *
477     * @return the hash code value for this map entry
478     * @see Object#hashCode()
479     * @see Object#equals(Object)
480     * @see #equals(Object)
481     */
482     int hashCode();
483    
484     /**
485     * Returns a comparator that compares {@link Map.Entry} in natural order on key.
486     *
487     * <p>The returned comparator is serializable and throws {@link
488     * NullPointerException} when comparing an entry with a null key.
489     *
490     * @param <K> the {@link Comparable} type of then map keys
491     * @param <V> the type of the map values
492     * @return a comparator that compares {@link Map.Entry} in natural order on key.
493     * @see Comparable
494     * @since 1.8
495     */
496 jsr166 1.3 public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {
497 jsr166 1.1 return (Comparator<Map.Entry<K, V>> & Serializable)
498     (c1, c2) -> c1.getKey().compareTo(c2.getKey());
499     }
500    
501     /**
502     * Returns a comparator that compares {@link Map.Entry} in natural order on value.
503     *
504     * <p>The returned comparator is serializable and throws {@link
505     * NullPointerException} when comparing an entry with null values.
506     *
507     * @param <K> the type of the map keys
508     * @param <V> the {@link Comparable} type of the map values
509     * @return a comparator that compares {@link Map.Entry} in natural order on value.
510     * @see Comparable
511     * @since 1.8
512     */
513 jsr166 1.3 public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
514 jsr166 1.1 return (Comparator<Map.Entry<K, V>> & Serializable)
515     (c1, c2) -> c1.getValue().compareTo(c2.getValue());
516     }
517    
518     /**
519     * Returns a comparator that compares {@link Map.Entry} by key using the given
520     * {@link Comparator}.
521     *
522     * <p>The returned comparator is serializable if the specified comparator
523     * is also serializable.
524     *
525     * @param <K> the type of the map keys
526     * @param <V> the type of the map values
527     * @param cmp the key {@link Comparator}
528     * @return a comparator that compares {@link Map.Entry} by the key.
529     * @since 1.8
530     */
531     public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
532     Objects.requireNonNull(cmp);
533     return (Comparator<Map.Entry<K, V>> & Serializable)
534     (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
535     }
536    
537     /**
538     * Returns a comparator that compares {@link Map.Entry} by value using the given
539     * {@link Comparator}.
540     *
541     * <p>The returned comparator is serializable if the specified comparator
542     * is also serializable.
543     *
544     * @param <K> the type of the map keys
545     * @param <V> the type of the map values
546     * @param cmp the value {@link Comparator}
547     * @return a comparator that compares {@link Map.Entry} by the value.
548     * @since 1.8
549     */
550     public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
551     Objects.requireNonNull(cmp);
552     return (Comparator<Map.Entry<K, V>> & Serializable)
553     (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
554     }
555     }
556    
557     // Comparison and hashing
558    
559     /**
560     * Compares the specified object with this map for equality. Returns
561     * {@code true} if the given object is also a map and the two maps
562     * represent the same mappings. More formally, two maps {@code m1} and
563     * {@code m2} represent the same mappings if
564     * {@code m1.entrySet().equals(m2.entrySet())}. This ensures that the
565     * {@code equals} method works properly across different implementations
566     * of the {@code Map} interface.
567     *
568     * @param o object to be compared for equality with this map
569     * @return {@code true} if the specified object is equal to this map
570     */
571     boolean equals(Object o);
572    
573     /**
574     * Returns the hash code value for this map. The hash code of a map is
575     * defined to be the sum of the hash codes of each entry in the map's
576     * {@code entrySet()} view. This ensures that {@code m1.equals(m2)}
577     * implies that {@code m1.hashCode()==m2.hashCode()} for any two maps
578     * {@code m1} and {@code m2}, as required by the general contract of
579     * {@link Object#hashCode}.
580     *
581     * @return the hash code value for this map
582     * @see Map.Entry#hashCode()
583     * @see Object#equals(Object)
584     * @see #equals(Object)
585     */
586     int hashCode();
587    
588     // Defaultable methods
589    
590     /**
591     * Returns the value to which the specified key is mapped, or
592     * {@code defaultValue} if this map contains no mapping for the key.
593     *
594     * @implSpec
595     * The default implementation makes no guarantees about synchronization
596     * or atomicity properties of this method. Any implementation providing
597     * atomicity guarantees must override this method and document its
598     * concurrency properties.
599     *
600     * @param key the key whose associated value is to be returned
601     * @param defaultValue the default mapping of the key
602     * @return the value to which the specified key is mapped, or
603     * {@code defaultValue} if this map contains no mapping for the key
604     * @throws ClassCastException if the key is of an inappropriate type for
605     * this map
606 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
607 jsr166 1.1 * @throws NullPointerException if the specified key is null and this map
608     * does not permit null keys
609 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
610 jsr166 1.1 * @since 1.8
611     */
612     default V getOrDefault(Object key, V defaultValue) {
613     V v;
614     return (((v = get(key)) != null) || containsKey(key))
615     ? v
616     : defaultValue;
617     }
618    
619     /**
620     * Performs the given action for each entry in this map until all entries
621     * have been processed or the action throws an exception. Unless
622     * otherwise specified by the implementing class, actions are performed in
623     * the order of entry set iteration (if an iteration order is specified.)
624     * Exceptions thrown by the action are relayed to the caller.
625     *
626     * @implSpec
627     * The default implementation is equivalent to, for this {@code map}:
628     * <pre> {@code
629     * for (Map.Entry<K, V> entry : map.entrySet())
630     * action.accept(entry.getKey(), entry.getValue());
631     * }</pre>
632     *
633     * The default implementation makes no guarantees about synchronization
634     * or atomicity properties of this method. Any implementation providing
635     * atomicity guarantees must override this method and document its
636     * concurrency properties.
637     *
638     * @param action The action to be performed for each entry
639     * @throws NullPointerException if the specified action is null
640     * @throws ConcurrentModificationException if an entry is found to be
641     * removed during iteration
642     * @since 1.8
643     */
644     default void forEach(BiConsumer<? super K, ? super V> action) {
645     Objects.requireNonNull(action);
646     for (Map.Entry<K, V> entry : entrySet()) {
647     K k;
648     V v;
649     try {
650     k = entry.getKey();
651     v = entry.getValue();
652     } catch (IllegalStateException ise) {
653     // this usually means the entry is no longer in the map.
654     throw new ConcurrentModificationException(ise);
655     }
656     action.accept(k, v);
657     }
658     }
659    
660     /**
661     * Replaces each entry's value with the result of invoking the given
662     * function on that entry until all entries have been processed or the
663     * function throws an exception. Exceptions thrown by the function are
664     * relayed to the caller.
665     *
666     * @implSpec
667     * <p>The default implementation is equivalent to, for this {@code map}:
668     * <pre> {@code
669     * for (Map.Entry<K, V> entry : map.entrySet())
670     * entry.setValue(function.apply(entry.getKey(), entry.getValue()));
671     * }</pre>
672     *
673     * <p>The default implementation makes no guarantees about synchronization
674     * or atomicity properties of this method. Any implementation providing
675     * atomicity guarantees must override this method and document its
676     * concurrency properties.
677     *
678     * @param function the function to apply to each entry
679     * @throws UnsupportedOperationException if the {@code set} operation
680     * is not supported by this map's entry set iterator.
681     * @throws ClassCastException if the class of a replacement value
682     * prevents it from being stored in this map
683     * @throws NullPointerException if the specified function is null, or the
684     * specified replacement value is null, and this map does not permit null
685     * values
686     * @throws ClassCastException if a replacement value is of an inappropriate
687     * type for this map
688 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
689 jsr166 1.1 * @throws NullPointerException if function or a replacement value is null,
690     * and this map does not permit null keys or values
691 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
692 jsr166 1.1 * @throws IllegalArgumentException if some property of a replacement value
693     * prevents it from being stored in this map
694 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
695 jsr166 1.1 * @throws ConcurrentModificationException if an entry is found to be
696     * removed during iteration
697     * @since 1.8
698     */
699     default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
700     Objects.requireNonNull(function);
701     for (Map.Entry<K, V> entry : entrySet()) {
702     K k;
703     V v;
704     try {
705     k = entry.getKey();
706     v = entry.getValue();
707     } catch (IllegalStateException ise) {
708     // this usually means the entry is no longer in the map.
709     throw new ConcurrentModificationException(ise);
710     }
711    
712     // ise thrown from function is not a cme.
713     v = function.apply(k, v);
714    
715     try {
716     entry.setValue(v);
717     } catch (IllegalStateException ise) {
718     // this usually means the entry is no longer in the map.
719     throw new ConcurrentModificationException(ise);
720     }
721     }
722     }
723    
724     /**
725     * If the specified key is not already associated with a value (or is mapped
726     * to {@code null}) associates it with the given value and returns
727     * {@code null}, else returns the current value.
728     *
729     * @implSpec
730     * The default implementation is equivalent to, for this {@code
731     * map}:
732     *
733     * <pre> {@code
734     * V v = map.get(key);
735     * if (v == null)
736     * v = map.put(key, value);
737     *
738     * return v;
739     * }</pre>
740     *
741     * <p>The default implementation makes no guarantees about synchronization
742     * or atomicity properties of this method. Any implementation providing
743     * atomicity guarantees must override this method and document its
744     * concurrency properties.
745     *
746     * @param key key with which the specified value is to be associated
747     * @param value value to be associated with the specified key
748     * @return the previous value associated with the specified key, or
749     * {@code null} if there was no mapping for the key.
750     * (A {@code null} return can also indicate that the map
751     * previously associated {@code null} with the key,
752     * if the implementation supports null values.)
753     * @throws UnsupportedOperationException if the {@code put} operation
754     * is not supported by this map
755 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
756 jsr166 1.1 * @throws ClassCastException if the key or value is of an inappropriate
757     * type for this map
758 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
759 jsr166 1.1 * @throws NullPointerException if the specified key or value is null,
760     * and this map does not permit null keys or values
761 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
762 jsr166 1.1 * @throws IllegalArgumentException if some property of the specified key
763     * or value prevents it from being stored in this map
764 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
765 jsr166 1.1 * @since 1.8
766     */
767     default V putIfAbsent(K key, V value) {
768     V v = get(key);
769     if (v == null) {
770     v = put(key, value);
771     }
772    
773     return v;
774     }
775    
776     /**
777     * Removes the entry for the specified key only if it is currently
778     * mapped to the specified value.
779     *
780     * @implSpec
781     * The default implementation is equivalent to, for this {@code map}:
782     *
783     * <pre> {@code
784     * if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
785     * map.remove(key);
786     * return true;
787     * } else
788     * return false;
789     * }</pre>
790     *
791     * <p>The default implementation makes no guarantees about synchronization
792     * or atomicity properties of this method. Any implementation providing
793     * atomicity guarantees must override this method and document its
794     * concurrency properties.
795     *
796     * @param key key with which the specified value is associated
797     * @param value value expected to be associated with the specified key
798     * @return {@code true} if the value was removed
799     * @throws UnsupportedOperationException if the {@code remove} operation
800     * is not supported by this map
801 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
802 jsr166 1.1 * @throws ClassCastException if the key or value is of an inappropriate
803     * type for this map
804 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
805 jsr166 1.1 * @throws NullPointerException if the specified key or value is null,
806     * and this map does not permit null keys or values
807 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
808 jsr166 1.1 * @since 1.8
809     */
810     default boolean remove(Object key, Object value) {
811     Object curValue = get(key);
812     if (!Objects.equals(curValue, value) ||
813     (curValue == null && !containsKey(key))) {
814     return false;
815     }
816     remove(key);
817     return true;
818     }
819    
820     /**
821     * Replaces the entry for the specified key only if currently
822     * mapped to the specified value.
823     *
824     * @implSpec
825     * The default implementation is equivalent to, for this {@code map}:
826     *
827     * <pre> {@code
828     * if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
829     * map.put(key, newValue);
830     * return true;
831     * } else
832     * return false;
833     * }</pre>
834     *
835     * The default implementation does not throw NullPointerException
836     * for maps that do not support null values if oldValue is null unless
837     * newValue is also null.
838     *
839     * <p>The default implementation makes no guarantees about synchronization
840     * or atomicity properties of this method. Any implementation providing
841     * atomicity guarantees must override this method and document its
842     * concurrency properties.
843     *
844     * @param key key with which the specified value is associated
845     * @param oldValue value expected to be associated with the specified key
846     * @param newValue value to be associated with the specified key
847     * @return {@code true} if the value was replaced
848     * @throws UnsupportedOperationException if the {@code put} operation
849     * is not supported by this map
850 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
851 jsr166 1.1 * @throws ClassCastException if the class of a specified key or value
852     * prevents it from being stored in this map
853     * @throws NullPointerException if a specified key or newValue is null,
854     * and this map does not permit null keys or values
855     * @throws NullPointerException if oldValue is null and this map does not
856     * permit null values
857 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
858 jsr166 1.1 * @throws IllegalArgumentException if some property of a specified key
859     * or value prevents it from being stored in this map
860     * @since 1.8
861     */
862     default boolean replace(K key, V oldValue, V newValue) {
863     Object curValue = get(key);
864     if (!Objects.equals(curValue, oldValue) ||
865     (curValue == null && !containsKey(key))) {
866     return false;
867     }
868     put(key, newValue);
869     return true;
870     }
871    
872     /**
873     * Replaces the entry for the specified key only if it is
874     * currently mapped to some value.
875     *
876     * @implSpec
877     * The default implementation is equivalent to, for this {@code map}:
878     *
879     * <pre> {@code
880     * if (map.containsKey(key)) {
881     * return map.put(key, value);
882     * } else
883     * return null;
884     * }</pre>
885     *
886     * <p>The default implementation makes no guarantees about synchronization
887     * or atomicity properties of this method. Any implementation providing
888     * atomicity guarantees must override this method and document its
889     * concurrency properties.
890     *
891     * @param key key with which the specified value is associated
892     * @param value value to be associated with the specified key
893     * @return the previous value associated with the specified key, or
894     * {@code null} if there was no mapping for the key.
895     * (A {@code null} return can also indicate that the map
896     * previously associated {@code null} with the key,
897     * if the implementation supports null values.)
898     * @throws UnsupportedOperationException if the {@code put} operation
899     * is not supported by this map
900 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
901 jsr166 1.1 * @throws ClassCastException if the class of the specified key or value
902     * prevents it from being stored in this map
903 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
904 jsr166 1.1 * @throws NullPointerException if the specified key or value is null,
905     * and this map does not permit null keys or values
906     * @throws IllegalArgumentException if some property of the specified key
907     * or value prevents it from being stored in this map
908     * @since 1.8
909     */
910     default V replace(K key, V value) {
911     V curValue;
912     if (((curValue = get(key)) != null) || containsKey(key)) {
913     curValue = put(key, value);
914     }
915     return curValue;
916     }
917    
918     /**
919     * If the specified key is not already associated with a value (or is mapped
920     * to {@code null}), attempts to compute its value using the given mapping
921     * function and enters it into this map unless {@code null}.
922     *
923     * <p>If the mapping function returns {@code null}, no mapping is recorded.
924     * If the mapping function itself throws an (unchecked) exception, the
925     * exception is rethrown, and no mapping is recorded. The most
926     * common usage is to construct a new object serving as an initial
927     * mapped value or memoized result, as in:
928     *
929     * <pre> {@code
930     * map.computeIfAbsent(key, k -> new Value(f(k)));
931     * }</pre>
932     *
933     * <p>Or to implement a multi-value map, {@code Map<K,Collection<V>>},
934     * supporting multiple values per key:
935     *
936     * <pre> {@code
937     * map.computeIfAbsent(key, k -> new HashSet<V>()).add(v);
938     * }</pre>
939     *
940     * <p>The mapping function should not modify this map during computation.
941     *
942     * @implSpec
943     * The default implementation is equivalent to the following steps for this
944     * {@code map}, then returning the current value or {@code null} if now
945     * absent:
946     *
947     * <pre> {@code
948     * if (map.get(key) == null) {
949     * V newValue = mappingFunction.apply(key);
950     * if (newValue != null)
951     * map.put(key, newValue);
952     * }
953     * }</pre>
954     *
955     * <p>The default implementation makes no guarantees about detecting if the
956     * mapping function modifies this map during computation and, if
957     * appropriate, reporting an error. Non-concurrent implementations should
958     * override this method and, on a best-effort basis, throw a
959     * {@code ConcurrentModificationException} if it is detected that the
960     * mapping function modifies this map during computation. Concurrent
961     * implementations should override this method and, on a best-effort basis,
962     * throw an {@code IllegalStateException} if it is detected that the
963     * mapping function modifies this map during computation and as a result
964     * computation would never complete.
965     *
966     * <p>The default implementation makes no guarantees about synchronization
967     * or atomicity properties of this method. Any implementation providing
968     * atomicity guarantees must override this method and document its
969     * concurrency properties. In particular, all implementations of
970     * subinterface {@link java.util.concurrent.ConcurrentMap} must document
971     * whether the mapping function is applied once atomically only if the value
972     * is not present.
973     *
974     * @param key key with which the specified value is to be associated
975     * @param mappingFunction the mapping function to compute a value
976     * @return the current (existing or computed) value associated with
977     * the specified key, or null if the computed value is null
978     * @throws NullPointerException if the specified key is null and
979     * this map does not support null keys, or the mappingFunction
980     * is null
981     * @throws UnsupportedOperationException if the {@code put} operation
982     * is not supported by this map
983 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
984 jsr166 1.1 * @throws ClassCastException if the class of the specified key or value
985     * prevents it from being stored in this map
986 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
987 jsr166 1.2 * @throws IllegalArgumentException if some property of the specified key
988     * or value prevents it from being stored in this map
989 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
990 jsr166 1.1 * @since 1.8
991     */
992     default V computeIfAbsent(K key,
993     Function<? super K, ? extends V> mappingFunction) {
994     Objects.requireNonNull(mappingFunction);
995     V v;
996     if ((v = get(key)) == null) {
997     V newValue;
998     if ((newValue = mappingFunction.apply(key)) != null) {
999     put(key, newValue);
1000     return newValue;
1001     }
1002     }
1003    
1004     return v;
1005     }
1006    
1007     /**
1008     * If the value for the specified key is present and non-null, attempts to
1009     * compute a new mapping given the key and its current mapped value.
1010     *
1011     * <p>If the remapping function returns {@code null}, the mapping is removed.
1012     * If the remapping function itself throws an (unchecked) exception, the
1013     * exception is rethrown, and the current mapping is left unchanged.
1014     *
1015     * <p>The remapping function should not modify this map during computation.
1016     *
1017     * @implSpec
1018     * The default implementation is equivalent to performing the following
1019     * steps for this {@code map}, then returning the current value or
1020     * {@code null} if now absent:
1021     *
1022     * <pre> {@code
1023     * if (map.get(key) != null) {
1024     * V oldValue = map.get(key);
1025     * V newValue = remappingFunction.apply(key, oldValue);
1026     * if (newValue != null)
1027     * map.put(key, newValue);
1028     * else
1029     * map.remove(key);
1030     * }
1031     * }</pre>
1032     *
1033     * <p>The default implementation makes no guarantees about detecting if the
1034     * remapping function modifies this map during computation and, if
1035     * appropriate, reporting an error. Non-concurrent implementations should
1036     * override this method and, on a best-effort basis, throw a
1037     * {@code ConcurrentModificationException} if it is detected that the
1038     * remapping function modifies this map during computation. Concurrent
1039     * implementations should override this method and, on a best-effort basis,
1040     * throw an {@code IllegalStateException} if it is detected that the
1041     * remapping function modifies this map during computation and as a result
1042     * computation would never complete.
1043     *
1044     * <p>The default implementation makes no guarantees about synchronization
1045     * or atomicity properties of this method. Any implementation providing
1046     * atomicity guarantees must override this method and document its
1047     * concurrency properties. In particular, all implementations of
1048     * subinterface {@link java.util.concurrent.ConcurrentMap} must document
1049     * whether the remapping function is applied once atomically only if the
1050     * value is not present.
1051     *
1052     * @param key key with which the specified value is to be associated
1053     * @param remappingFunction the remapping function to compute a value
1054     * @return the new value associated with the specified key, or null if none
1055     * @throws NullPointerException if the specified key is null and
1056     * this map does not support null keys, or the
1057     * remappingFunction is null
1058     * @throws UnsupportedOperationException if the {@code put} operation
1059     * is not supported by this map
1060 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
1061 jsr166 1.1 * @throws ClassCastException if the class of the specified key or value
1062     * prevents it from being stored in this map
1063 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
1064 jsr166 1.2 * @throws IllegalArgumentException if some property of the specified key
1065     * or value prevents it from being stored in this map
1066 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
1067 jsr166 1.1 * @since 1.8
1068     */
1069     default V computeIfPresent(K key,
1070     BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1071     Objects.requireNonNull(remappingFunction);
1072     V oldValue;
1073     if ((oldValue = get(key)) != null) {
1074     V newValue = remappingFunction.apply(key, oldValue);
1075     if (newValue != null) {
1076     put(key, newValue);
1077     return newValue;
1078     } else {
1079     remove(key);
1080     return null;
1081     }
1082     } else {
1083     return null;
1084     }
1085     }
1086    
1087     /**
1088     * Attempts to compute a mapping for the specified key and its current
1089     * mapped value (or {@code null} if there is no current mapping). For
1090     * example, to either create or append a {@code String} msg to a value
1091     * mapping:
1092     *
1093     * <pre> {@code
1094     * map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre>
1095     * (Method {@link #merge merge()} is often simpler to use for such purposes.)
1096     *
1097     * <p>If the remapping function returns {@code null}, the mapping is removed
1098     * (or remains absent if initially absent). If the remapping function
1099     * itself throws an (unchecked) exception, the exception is rethrown, and
1100     * the current mapping is left unchanged.
1101     *
1102     * <p>The remapping function should not modify this map during computation.
1103     *
1104     * @implSpec
1105     * The default implementation is equivalent to performing the following
1106     * steps for this {@code map}, then returning the current value or
1107     * {@code null} if absent:
1108     *
1109     * <pre> {@code
1110     * V oldValue = map.get(key);
1111     * V newValue = remappingFunction.apply(key, oldValue);
1112 jsr166 1.3 * if (oldValue != null) {
1113 jsr166 1.1 * if (newValue != null)
1114     * map.put(key, newValue);
1115     * else
1116     * map.remove(key);
1117     * } else {
1118     * if (newValue != null)
1119     * map.put(key, newValue);
1120     * else
1121     * return null;
1122     * }
1123     * }</pre>
1124     *
1125     * <p>The default implementation makes no guarantees about detecting if the
1126     * remapping function modifies this map during computation and, if
1127     * appropriate, reporting an error. Non-concurrent implementations should
1128     * override this method and, on a best-effort basis, throw a
1129     * {@code ConcurrentModificationException} if it is detected that the
1130     * remapping function modifies this map during computation. Concurrent
1131     * implementations should override this method and, on a best-effort basis,
1132     * throw an {@code IllegalStateException} if it is detected that the
1133     * remapping function modifies this map during computation and as a result
1134     * computation would never complete.
1135     *
1136     * <p>The default implementation makes no guarantees about synchronization
1137     * or atomicity properties of this method. Any implementation providing
1138     * atomicity guarantees must override this method and document its
1139     * concurrency properties. In particular, all implementations of
1140     * subinterface {@link java.util.concurrent.ConcurrentMap} must document
1141     * whether the remapping function is applied once atomically only if the
1142     * value is not present.
1143     *
1144     * @param key key with which the specified value is to be associated
1145     * @param remappingFunction the remapping function to compute a value
1146     * @return the new value associated with the specified key, or null if none
1147     * @throws NullPointerException if the specified key is null and
1148     * this map does not support null keys, or the
1149     * remappingFunction is null
1150     * @throws UnsupportedOperationException if the {@code put} operation
1151     * is not supported by this map
1152 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
1153 jsr166 1.1 * @throws ClassCastException if the class of the specified key or value
1154     * prevents it from being stored in this map
1155 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
1156 jsr166 1.2 * @throws IllegalArgumentException if some property of the specified key
1157     * or value prevents it from being stored in this map
1158 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
1159 jsr166 1.1 * @since 1.8
1160     */
1161     default V compute(K key,
1162     BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1163     Objects.requireNonNull(remappingFunction);
1164     V oldValue = get(key);
1165    
1166     V newValue = remappingFunction.apply(key, oldValue);
1167     if (newValue == null) {
1168     // delete mapping
1169     if (oldValue != null || containsKey(key)) {
1170     // something to remove
1171     remove(key);
1172     return null;
1173     } else {
1174     // nothing to do. Leave things as they were.
1175     return null;
1176     }
1177     } else {
1178     // add or replace old mapping
1179     put(key, newValue);
1180     return newValue;
1181     }
1182     }
1183    
1184     /**
1185     * If the specified key is not already associated with a value or is
1186     * associated with null, associates it with the given non-null value.
1187     * Otherwise, replaces the associated value with the results of the given
1188     * remapping function, or removes if the result is {@code null}. This
1189     * method may be of use when combining multiple mapped values for a key.
1190     * For example, to either create or append a {@code String msg} to a
1191     * value mapping:
1192     *
1193     * <pre> {@code
1194     * map.merge(key, msg, String::concat)
1195     * }</pre>
1196     *
1197     * <p>If the remapping function returns {@code null}, the mapping is removed.
1198     * If the remapping function itself throws an (unchecked) exception, the
1199     * exception is rethrown, and the current mapping is left unchanged.
1200     *
1201     * <p>The remapping function should not modify this map during computation.
1202     *
1203     * @implSpec
1204     * The default implementation is equivalent to performing the following
1205     * steps for this {@code map}, then returning the current value or
1206     * {@code null} if absent:
1207     *
1208     * <pre> {@code
1209     * V oldValue = map.get(key);
1210     * V newValue = (oldValue == null) ? value :
1211     * remappingFunction.apply(oldValue, value);
1212     * if (newValue == null)
1213     * map.remove(key);
1214     * else
1215     * map.put(key, newValue);
1216     * }</pre>
1217     *
1218     * <p>The default implementation makes no guarantees about detecting if the
1219     * remapping function modifies this map during computation and, if
1220     * appropriate, reporting an error. Non-concurrent implementations should
1221     * override this method and, on a best-effort basis, throw a
1222     * {@code ConcurrentModificationException} if it is detected that the
1223     * remapping function modifies this map during computation. Concurrent
1224     * implementations should override this method and, on a best-effort basis,
1225     * throw an {@code IllegalStateException} if it is detected that the
1226     * remapping function modifies this map during computation and as a result
1227     * computation would never complete.
1228     *
1229     * <p>The default implementation makes no guarantees about synchronization
1230     * or atomicity properties of this method. Any implementation providing
1231     * atomicity guarantees must override this method and document its
1232     * concurrency properties. In particular, all implementations of
1233     * subinterface {@link java.util.concurrent.ConcurrentMap} must document
1234     * whether the remapping function is applied once atomically only if the
1235     * value is not present.
1236     *
1237     * @param key key with which the resulting value is to be associated
1238     * @param value the non-null value to be merged with the existing value
1239     * associated with the key or, if no existing value or a null value
1240     * is associated with the key, to be associated with the key
1241     * @param remappingFunction the remapping function to recompute a value if
1242     * present
1243     * @return the new value associated with the specified key, or null if no
1244     * value is associated with the key
1245     * @throws UnsupportedOperationException if the {@code put} operation
1246     * is not supported by this map
1247 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
1248 jsr166 1.1 * @throws ClassCastException if the class of the specified key or value
1249     * prevents it from being stored in this map
1250 jsr166 1.3 * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
1251     * @throws IllegalArgumentException if some property of the specified key
1252     * or value prevents it from being stored in this map
1253     * (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
1254 jsr166 1.1 * @throws NullPointerException if the specified key is null and this map
1255     * does not support null keys or the value or remappingFunction is
1256     * null
1257     * @since 1.8
1258     */
1259     default V merge(K key, V value,
1260     BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
1261     Objects.requireNonNull(remappingFunction);
1262     Objects.requireNonNull(value);
1263     V oldValue = get(key);
1264     V newValue = (oldValue == null) ? value :
1265     remappingFunction.apply(oldValue, value);
1266     if (newValue == null) {
1267     remove(key);
1268     } else {
1269     put(key, newValue);
1270     }
1271     return newValue;
1272     }
1273 jsr166 1.3
1274     /**
1275     * Returns an immutable map containing zero mappings.
1276     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1277     *
1278     * @param <K> the {@code Map}'s key type
1279     * @param <V> the {@code Map}'s value type
1280     * @return an empty {@code Map}
1281     *
1282     * @since 9
1283     */
1284     static <K, V> Map<K, V> of() {
1285     return Collections.emptyMap();
1286     }
1287    
1288     /**
1289     * Returns an immutable map containing a single mapping.
1290     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1291     *
1292     * @param <K> the {@code Map}'s key type
1293     * @param <V> the {@code Map}'s value type
1294     * @param k1 the mapping's key
1295     * @param v1 the mapping's value
1296     * @return a {@code Map} containing the specified mapping
1297     * @throws NullPointerException if the key or the value is {@code null}
1298     *
1299     * @since 9
1300     */
1301     static <K, V> Map<K, V> of(K k1, V v1) {
1302     return Collections.singletonMap(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
1303     }
1304    
1305     /**
1306     * Returns an immutable map containing two mappings.
1307     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1308     *
1309     * @param <K> the {@code Map}'s key type
1310     * @param <V> the {@code Map}'s value type
1311     * @param k1 the first mapping's key
1312     * @param v1 the first mapping's value
1313     * @param k2 the second mapping's key
1314     * @param v2 the second mapping's value
1315     * @return a {@code Map} containing the specified mappings
1316     * @throws IllegalArgumentException if the keys are duplicates
1317     * @throws NullPointerException if any key or value is {@code null}
1318     *
1319     * @since 9
1320     */
1321     static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2) {
1322     Map<K, V> map = new HashMap<>(3); // specify number of buckets to avoid resizing
1323     map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
1324     map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
1325     if (map.size() != 2) {
1326     throw new IllegalArgumentException("duplicate keys");
1327     }
1328     return Collections.unmodifiableMap(map);
1329     }
1330    
1331     /**
1332     * Returns an immutable map containing three mappings.
1333     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1334     *
1335     * @param <K> the {@code Map}'s key type
1336     * @param <V> the {@code Map}'s value type
1337     * @param k1 the first mapping's key
1338     * @param v1 the first mapping's value
1339     * @param k2 the second mapping's key
1340     * @param v2 the second mapping's value
1341     * @param k3 the third mapping's key
1342     * @param v3 the third mapping's value
1343     * @return a {@code Map} containing the specified mappings
1344     * @throws IllegalArgumentException if there are any duplicate keys
1345     * @throws NullPointerException if any key or value is {@code null}
1346     *
1347     * @since 9
1348     */
1349     static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
1350     Map<K, V> map = new HashMap<>(5); // specify number of buckets to avoid resizing
1351     map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
1352     map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
1353     map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
1354     if (map.size() != 3) {
1355     throw new IllegalArgumentException("duplicate keys");
1356     }
1357     return Collections.unmodifiableMap(map);
1358     }
1359    
1360     /**
1361     * Returns an immutable map containing four mappings.
1362     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1363     *
1364     * @param <K> the {@code Map}'s key type
1365     * @param <V> the {@code Map}'s value type
1366     * @param k1 the first mapping's key
1367     * @param v1 the first mapping's value
1368     * @param k2 the second mapping's key
1369     * @param v2 the second mapping's value
1370     * @param k3 the third mapping's key
1371     * @param v3 the third mapping's value
1372     * @param k4 the fourth mapping's key
1373     * @param v4 the fourth mapping's value
1374     * @return a {@code Map} containing the specified mappings
1375     * @throws IllegalArgumentException if there are any duplicate keys
1376     * @throws NullPointerException if any key or value is {@code null}
1377     *
1378     * @since 9
1379     */
1380     static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
1381     Map<K, V> map = new HashMap<>(6); // specify number of buckets to avoid resizing
1382     map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
1383     map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
1384     map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
1385     map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
1386     if (map.size() != 4) {
1387     throw new IllegalArgumentException("duplicate keys");
1388     }
1389     return Collections.unmodifiableMap(map);
1390     }
1391    
1392     /**
1393     * Returns an immutable map containing five mappings.
1394     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1395     *
1396     * @param <K> the {@code Map}'s key type
1397     * @param <V> the {@code Map}'s value type
1398     * @param k1 the first mapping's key
1399     * @param v1 the first mapping's value
1400     * @param k2 the second mapping's key
1401     * @param v2 the second mapping's value
1402     * @param k3 the third mapping's key
1403     * @param v3 the third mapping's value
1404     * @param k4 the fourth mapping's key
1405     * @param v4 the fourth mapping's value
1406     * @param k5 the fifth mapping's key
1407     * @param v5 the fifth mapping's value
1408     * @return a {@code Map} containing the specified mappings
1409     * @throws IllegalArgumentException if there are any duplicate keys
1410     * @throws NullPointerException if any key or value is {@code null}
1411     *
1412     * @since 9
1413     */
1414     static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
1415     Map<K, V> map = new HashMap<>(7); // specify number of buckets to avoid resizing
1416     map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
1417     map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
1418     map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
1419     map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
1420     map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
1421     if (map.size() != 5) {
1422     throw new IllegalArgumentException("duplicate keys");
1423     }
1424     return Collections.unmodifiableMap(map);
1425     }
1426    
1427     /**
1428     * Returns an immutable map containing six mappings.
1429     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1430     *
1431     * @param <K> the {@code Map}'s key type
1432     * @param <V> the {@code Map}'s value type
1433     * @param k1 the first mapping's key
1434     * @param v1 the first mapping's value
1435     * @param k2 the second mapping's key
1436     * @param v2 the second mapping's value
1437     * @param k3 the third mapping's key
1438     * @param v3 the third mapping's value
1439     * @param k4 the fourth mapping's key
1440     * @param v4 the fourth mapping's value
1441     * @param k5 the fifth mapping's key
1442     * @param v5 the fifth mapping's value
1443     * @param k6 the sixth mapping's key
1444     * @param v6 the sixth mapping's value
1445     * @return a {@code Map} containing the specified mappings
1446     * @throws IllegalArgumentException if there are any duplicate keys
1447     * @throws NullPointerException if any key or value is {@code null}
1448     *
1449     * @since 9
1450     */
1451     static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
1452     K k6, V v6) {
1453     Map<K, V> map = new HashMap<>(9); // specify number of buckets to avoid resizing
1454     map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
1455     map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
1456     map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
1457     map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
1458     map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
1459     map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
1460     if (map.size() != 6) {
1461     throw new IllegalArgumentException("duplicate keys");
1462     }
1463     return Collections.unmodifiableMap(map);
1464     }
1465    
1466     /**
1467     * Returns an immutable map containing seven mappings.
1468     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1469     *
1470     * @param <K> the {@code Map}'s key type
1471     * @param <V> the {@code Map}'s value type
1472     * @param k1 the first mapping's key
1473     * @param v1 the first mapping's value
1474     * @param k2 the second mapping's key
1475     * @param v2 the second mapping's value
1476     * @param k3 the third mapping's key
1477     * @param v3 the third mapping's value
1478     * @param k4 the fourth mapping's key
1479     * @param v4 the fourth mapping's value
1480     * @param k5 the fifth mapping's key
1481     * @param v5 the fifth mapping's value
1482     * @param k6 the sixth mapping's key
1483     * @param v6 the sixth mapping's value
1484     * @param k7 the seventh mapping's key
1485     * @param v7 the seventh mapping's value
1486     * @return a {@code Map} containing the specified mappings
1487     * @throws IllegalArgumentException if there are any duplicate keys
1488     * @throws NullPointerException if any key or value is {@code null}
1489     *
1490     * @since 9
1491     */
1492     static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
1493     K k6, V v6, K k7, V v7) {
1494     Map<K, V> map = new HashMap<>(10); // specify number of buckets to avoid resizing
1495     map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
1496     map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
1497     map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
1498     map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
1499     map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
1500     map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
1501     map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
1502     if (map.size() != 7) {
1503     throw new IllegalArgumentException("duplicate keys");
1504     }
1505     return Collections.unmodifiableMap(map);
1506     }
1507    
1508     /**
1509     * Returns an immutable map containing eight mappings.
1510     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1511     *
1512     * @param <K> the {@code Map}'s key type
1513     * @param <V> the {@code Map}'s value type
1514     * @param k1 the first mapping's key
1515     * @param v1 the first mapping's value
1516     * @param k2 the second mapping's key
1517     * @param v2 the second mapping's value
1518     * @param k3 the third mapping's key
1519     * @param v3 the third mapping's value
1520     * @param k4 the fourth mapping's key
1521     * @param v4 the fourth mapping's value
1522     * @param k5 the fifth mapping's key
1523     * @param v5 the fifth mapping's value
1524     * @param k6 the sixth mapping's key
1525     * @param v6 the sixth mapping's value
1526     * @param k7 the seventh mapping's key
1527     * @param v7 the seventh mapping's value
1528     * @param k8 the eighth mapping's key
1529     * @param v8 the eighth mapping's value
1530     * @return a {@code Map} containing the specified mappings
1531     * @throws IllegalArgumentException if there are any duplicate keys
1532     * @throws NullPointerException if any key or value is {@code null}
1533     *
1534     * @since 9
1535     */
1536     static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
1537     K k6, V v6, K k7, V v7, K k8, V v8) {
1538     Map<K, V> map = new HashMap<>(11); // specify number of buckets to avoid resizing
1539     map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
1540     map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
1541     map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
1542     map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
1543     map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
1544     map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
1545     map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
1546     map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
1547     if (map.size() != 8) {
1548     throw new IllegalArgumentException("duplicate keys");
1549     }
1550     return Collections.unmodifiableMap(map);
1551     }
1552    
1553     /**
1554     * Returns an immutable map containing nine mappings.
1555     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1556     *
1557     * @param <K> the {@code Map}'s key type
1558     * @param <V> the {@code Map}'s value type
1559     * @param k1 the first mapping's key
1560     * @param v1 the first mapping's value
1561     * @param k2 the second mapping's key
1562     * @param v2 the second mapping's value
1563     * @param k3 the third mapping's key
1564     * @param v3 the third mapping's value
1565     * @param k4 the fourth mapping's key
1566     * @param v4 the fourth mapping's value
1567     * @param k5 the fifth mapping's key
1568     * @param v5 the fifth mapping's value
1569     * @param k6 the sixth mapping's key
1570     * @param v6 the sixth mapping's value
1571     * @param k7 the seventh mapping's key
1572     * @param v7 the seventh mapping's value
1573     * @param k8 the eighth mapping's key
1574     * @param v8 the eighth mapping's value
1575     * @param k9 the ninth mapping's key
1576     * @param v9 the ninth mapping's value
1577     * @return a {@code Map} containing the specified mappings
1578     * @throws IllegalArgumentException if there are any duplicate keys
1579     * @throws NullPointerException if any key or value is {@code null}
1580     *
1581     * @since 9
1582     */
1583     static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
1584     K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) {
1585     Map<K, V> map = new HashMap<>(13); // specify number of buckets to avoid resizing
1586     map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
1587     map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
1588     map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
1589     map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
1590     map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
1591     map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
1592     map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
1593     map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
1594     map.put(Objects.requireNonNull(k9), Objects.requireNonNull(v9));
1595     if (map.size() != 9) {
1596     throw new IllegalArgumentException("duplicate keys");
1597     }
1598     return Collections.unmodifiableMap(map);
1599     }
1600    
1601     /**
1602     * Returns an immutable map containing ten mappings.
1603     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1604     *
1605     * @param <K> the {@code Map}'s key type
1606     * @param <V> the {@code Map}'s value type
1607     * @param k1 the first mapping's key
1608     * @param v1 the first mapping's value
1609     * @param k2 the second mapping's key
1610     * @param v2 the second mapping's value
1611     * @param k3 the third mapping's key
1612     * @param v3 the third mapping's value
1613     * @param k4 the fourth mapping's key
1614     * @param v4 the fourth mapping's value
1615     * @param k5 the fifth mapping's key
1616     * @param v5 the fifth mapping's value
1617     * @param k6 the sixth mapping's key
1618     * @param v6 the sixth mapping's value
1619     * @param k7 the seventh mapping's key
1620     * @param v7 the seventh mapping's value
1621     * @param k8 the eighth mapping's key
1622     * @param v8 the eighth mapping's value
1623     * @param k9 the ninth mapping's key
1624     * @param v9 the ninth mapping's value
1625     * @param k10 the tenth mapping's key
1626     * @param v10 the tenth mapping's value
1627     * @return a {@code Map} containing the specified mappings
1628     * @throws IllegalArgumentException if there are any duplicate keys
1629     * @throws NullPointerException if any key or value is {@code null}
1630     *
1631     * @since 9
1632     */
1633     static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
1634     K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) {
1635     Map<K, V> map = new HashMap<>(14); // specify number of buckets to avoid resizing
1636     map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
1637     map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
1638     map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
1639     map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
1640     map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
1641     map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
1642     map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
1643     map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
1644     map.put(Objects.requireNonNull(k9), Objects.requireNonNull(v9));
1645     map.put(Objects.requireNonNull(k10), Objects.requireNonNull(v10));
1646     if (map.size() != 10) {
1647     throw new IllegalArgumentException("duplicate keys");
1648     }
1649     return Collections.unmodifiableMap(map);
1650     }
1651    
1652     /**
1653     * Returns an immutable map containing keys and values extracted from the given entries.
1654     * The entries themselves are not stored in the map.
1655     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
1656     *
1657     * @apiNote
1658     * It is convenient to create the map entries using the {@link Map#entry Map.entry()} method.
1659     * For example,
1660     *
1661     * <pre>{@code
1662     * import static java.util.Map.entry;
1663     *
1664     * Map<Integer,String> map = Map.ofEntries(
1665     * entry(1, "a"),
1666     * entry(2, "b"),
1667     * entry(3, "c"),
1668     * ...
1669     * entry(26, "z"));
1670     * }</pre>
1671     *
1672     * @param <K> the {@code Map}'s key type
1673     * @param <V> the {@code Map}'s value type
1674     * @param entries {@code Map.Entry}s containing the keys and values from which the map is populated
1675     * @return a {@code Map} containing the specified mappings
1676     * @throws IllegalArgumentException if there are any duplicate keys
1677     * @throws NullPointerException if any entry, key, or value is {@code null}, or if
1678     * the {@code entries} array is {@code null}
1679     *
1680     * @see Map#entry Map.entry()
1681     * @since 9
1682     */
1683     @SafeVarargs
1684     @SuppressWarnings("varargs")
1685     static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
1686     Map<K, V> map = new HashMap<>(entries.length * 4 / 3 + 1); // throws NPE if entries is null
1687     for (Entry<? extends K, ? extends V> e : entries) {
1688     // next line throws NPE if e is null
1689     map.put(Objects.requireNonNull(e.getKey()), Objects.requireNonNull(e.getValue()));
1690     }
1691     if (map.size() != entries.length) {
1692     throw new IllegalArgumentException("duplicate keys");
1693     }
1694     return Collections.unmodifiableMap(map);
1695     }
1696    
1697     /**
1698     * Returns an immutable {@link Entry} containing the given key and value.
1699     * These entries are suitable for populating {@code Map} instances using the
1700     * {@link Map#ofEntries Map.ofEntries()} method.
1701     * The {@code Entry} instances created by this method have the following characteristics:
1702     *
1703     * <ul>
1704     * <li>They disallow {@code null} keys and values. Attempts to create them using a {@code null}
1705     * key or value result in {@code NullPointerException}.
1706     * <li>They are immutable. Calls to {@link Entry#setValue Entry.setValue()}
1707     * on a returned {@code Entry} result in {@code UnsupportedOperationException}.
1708     * <li>They are not serializable.
1709     * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
1710     * Callers should make no assumptions about the identity of the returned instances.
1711     * This method is free to create new instances or reuse existing ones. Therefore,
1712     * identity-sensitive operations on these instances (reference equality ({@code ==}),
1713     * identity hash code, and synchronization) are unreliable and should be avoided.
1714     * </ul>
1715     *
1716     * @apiNote
1717     * For a serializable {@code Entry}, see {@link AbstractMap.SimpleEntry} or
1718     * {@link AbstractMap.SimpleImmutableEntry}.
1719     *
1720     * @param <K> the key's type
1721     * @param <V> the value's type
1722     * @param k the key
1723     * @param v the value
1724     * @return an {@code Entry} containing the specified key and value
1725     * @throws NullPointerException if the key or value is {@code null}
1726     *
1727     * @see Map#ofEntries Map.ofEntries()
1728     * @since 9
1729     */
1730     static <K, V> Entry<K, V> entry(K k, V v) {
1731     // KeyValueHolder checks for nulls
1732     return new KeyValueHolder<>(k, v);
1733     }
1734 jsr166 1.1 }