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