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