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