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