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