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 * @return the value to which the specified key is mapped, or 565 * {@code defaultValue} if this map contains no mapping for the key 566 * @throws ClassCastException if the key is of an inappropriate type for 567 * this map 568 * (<a href="Collection.html#optional-restrictions">optional</a>) 569 * @throws NullPointerException if the specified key is null and this map 570 * does not permit null keys 571 * (<a href="Collection.html#optional-restrictions">optional</a>) 572 */ 573 default V getOrDefault(Object key, V defaultValue) { 574 V v; 575 return (((v = get(key)) != null) || containsKey(key)) 576 ? v 577 : defaultValue; 578 } 579 580 /** 581 * Performs the given action on each entry in this map, in the order entries 582 * are returned by an entry set iterator (which may be unspecified), until 583 * all entries have been processed or the action throws an {@code Exception}. 584 * Exceptions thrown by the action are relayed to the caller. 585 * 586 * <p>The default implementation should be overridden by implementations if 587 * they can provide a more performant implementation than an iterator-based 588 * one. 589 * 590 * <p>The default implementation makes no guarantees about synchronization 591 * or atomicity properties of this method. Any implementation providing 592 * atomicity guarantees must override this method and document its 593 * concurrency properties. 594 * 595 * @implSpec The default implementation is equivalent to, for this 596 * {@code map}: 597 * <pre> {@code 598 * for ((Map.Entry<K, V> entry : map.entrySet()) 599 * action.accept(entry.getKey(), entry.getValue()); 600 * }</pre> 601 * 602 * @param action The action to be performed for each entry 603 * @throws NullPointerException if the specified action is null 604 * @throws ConcurrentModificationException if an entry is found to be 605 * removed during iteration 606 * @since 1.8 607 */ 608 default void forEach(BiConsumer<? super K, ? super V> action) { 609 Objects.requireNonNull(action); 610 for (Map.Entry<K, V> entry : entrySet()) { 611 K k; 612 V v; 613 try { 614 k = entry.getKey(); 615 v = entry.getValue(); 616 } catch(IllegalStateException ise) { 617 // this usually means the entry is no longer in the map. 618 throw new ConcurrentModificationException(ise); 619 } 620 action.accept(k, v); 621 } 622 } 623 624 /** 625 * Replaces each entry's value with the result of invoking the given 626 * function on that entry, in the order entries are returned by an entry 627 * set iterator, until all entries have been processed or the function 628 * throws an exception. 629 * 630 * <p>The default implementation makes no guarantees about synchronization 631 * or atomicity properties of this method. Any implementation providing 632 * atomicity guarantees must override this method and document its 633 * concurrency properties. 634 * 635 * @implSpec 636 * <p>The default implementation is equivalent to, for this {@code map}: 637 * <pre> {@code 638 * for ((Map.Entry<K, V> entry : map.entrySet()) 639 * entry.setValue(function.apply(entry.getKey(), entry.getValue())); 640 * }</pre> 641 * 642 * @param function the function to apply to each entry 643 * @throws UnsupportedOperationException if the {@code set} operation 644 * is not supported by this map's entry set iterator. 645 * @throws ClassCastException if the class of a replacement value 646 * prevents it from being stored in this map 647 * @throws NullPointerException if the specified function is null, or the 648 * specified replacement value is null, and this map does not permit null 649 * values 650 * @throws ClassCastException if a replacement value is of an inappropriate 651 * type for this map 652 * (<a href="Collection.html#optional-restrictions">optional</a>) 653 * @throws NullPointerException if function or a replacement value is null, 654 * and this map does not permit null keys or values 655 * (<a href="Collection.html#optional-restrictions">optional</a>) 656 * @throws IllegalArgumentException if some property of a replacement value 657 * prevents it from being stored in this map 658 * (<a href="Collection.html#optional-restrictions">optional</a>) 659 * @throws ConcurrentModificationException if an entry is found to be 660 * removed during iteration 661 * @since 1.8 662 */ 663 default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { 664 Objects.requireNonNull(function); 665 for (Map.Entry<K, V> entry : entrySet()) { 666 K k; 667 V v; 668 try { 669 k = entry.getKey(); 670 v = entry.getValue(); 671 } catch(IllegalStateException ise) { 672 // this usually means the entry is no longer in the map. 673 throw new ConcurrentModificationException(ise); 674 } 675 676 // ise thrown from function is not a cme. 677 v = function.apply(k, v); 678 679 try { 680 entry.setValue(v); 681 } catch(IllegalStateException ise) { 682 // this usually means the entry is no longer in the map. 683 throw new ConcurrentModificationException(ise); 684 } 685 } 686 } 687 688 /** 689 * If the specified key is not already associated with a value (or is mapped 690 * to {@code null}) associates it with the given value and returns 691 * {@code null}, else returns the current value. 692 * 693 * <p>The default implementation makes no guarantees about synchronization 694 * or atomicity properties of this method. Any implementation providing 695 * atomicity guarantees must override this method and document its 696 * concurrency properties. 697 * 698 * @implSpec 699 * The default implementation is equivalent to, for this {@code 700 * map}: 701 * 702 * <pre> {@code 703 * if (map.get(key) == null) 704 * return map.put(key, value); 705 * else 706 * return map.get(key); 707 * }</pre> 708 * 709 * @param key key with which the specified value is to be associated 710 * @param value value to be associated with the specified key 711 * @return the previous value associated with the specified key, or 712 * {@code null} if there was no mapping for the key. 713 * (A {@code null} return can also indicate that the map 714 * previously associated {@code null} with the key, 715 * if the implementation supports null values.) 716 * @throws UnsupportedOperationException if the {@code put} operation 717 * is not supported by this map 718 * (<a href="Collection.html#optional-restrictions">optional</a>) 719 * @throws ClassCastException if the key or value is of an inappropriate 720 * type for this map 721 * (<a href="Collection.html#optional-restrictions">optional</a>) 722 * @throws NullPointerException if the specified key or value is null, 723 * and this map does not permit null keys or values 724 * (<a href="Collection.html#optional-restrictions">optional</a>) 725 * @throws IllegalArgumentException if some property of the specified key 726 * or value prevents it from being stored in this map 727 * (<a href="Collection.html#optional-restrictions">optional</a>) 728 * @throws ConcurrentModificationException if a modification of the map is 729 * detected during insertion of the value. 730 * @since 1.8 731 */ 732 default V putIfAbsent(K key, V value) { 733 V v = get(key); 734 if (v == null) { 735 if (put(key, value) != null) { 736 throw new ConcurrentModificationException(); 737 } 738 } 739 740 return v; 741 } 742 743 /** 744 * Removes the entry for the specified key only if it is currently 745 * mapped to the specified value. 746 * 747 * <p>The default implementation makes no guarantees about synchronization 748 * or atomicity properties of this method. Any implementation providing 749 * atomicity guarantees must override this method and document its 750 * concurrency properties. 751 * 752 * @implSpec 753 * The default implementation is equivalent to, for this {@code map}: 754 * 755 * <pre> {@code 756 * if (map.containsKey(key) && Objects.equals(map.get(key), value)) { 757 * map.remove(key); 758 * return true; 759 * } else 760 * return false; 761 * }</pre> 762 * 763 * @param key key with which the specified value is associated 764 * @param value value expected to be associated with the specified key 765 * @return {@code true} if the value was removed 766 * @throws UnsupportedOperationException if the {@code remove} operation 767 * is not supported by this map 768 * (<a href="Collection.html#optional-restrictions">optional</a>) 769 * @throws ClassCastException if the key or value is of an inappropriate 770 * type for this map 771 * (<a href="Collection.html#optional-restrictions">optional</a>) 772 * @throws NullPointerException if the specified key or value is null, 773 * and this map does not permit null keys or values 774 * (<a href="Collection.html#optional-restrictions">optional</a>) 775 * @since 1.8 776 */ 777 default boolean remove(Object key, Object value) { 778 Object curValue = get(key); 779 if (!Objects.equals(curValue, value) || 780 (curValue == null && !containsKey(key))) { 781 return false; 782 } 783 remove(key); 784 return true; 785 } 786 787 /** 788 * Replaces the entry for the specified key only if currently 789 * mapped to the specified value. 790 * 791 * <p>The default implementation makes no guarantees about synchronization 792 * or atomicity properties of this method. Any implementation providing 793 * atomicity guarantees must override this method and document its 794 * concurrency properties. 795 * 796 * @implSpec 797 * The default implementation is equivalent to, for this {@code map}: 798 * 799 * <pre> {@code 800 * if (map.containsKey(key) && Objects.equals(map.get(key), value)) { 801 * map.put(key, newValue); 802 * return true; 803 * } else 804 * return false; 805 * }</pre> 806 * 807 * @implNote The default implementation does not throw NullPointerException 808 * for maps that do not support null values if oldValue is null unless 809 * newValue is also null. 810 * 811 * @param key key with which the specified value is associated 812 * @param oldValue value expected to be associated with the specified key 813 * @param newValue value to be associated with the specified key 814 * @return {@code true} if the value was replaced 815 * @throws UnsupportedOperationException if the {@code put} operation 816 * is not supported by this map 817 * (<a href="Collection.html#optional-restrictions">optional</a>) 818 * @throws ClassCastException if the class of a specified key or value 819 * prevents it from being stored in this map 820 * @throws NullPointerException if a specified key or newValue is null, 821 * and this map does not permit null keys or values 822 * @throws NullPointerException if oldValue is null and this map does not 823 * permit null values 824 * (<a href="Collection.html#optional-restrictions">optional</a>) 825 * @throws IllegalArgumentException if some property of a specified key 826 * or value prevents it from being stored in this map 827 * @since 1.8 828 */ 829 default boolean replace(K key, V oldValue, V newValue) { 830 Object curValue = get(key); 831 if (!Objects.equals(curValue, oldValue) || 832 (curValue == null && !containsKey(key))) { 833 return false; 834 } 835 put(key, newValue); 836 return true; 837 } 838 839 /** 840 * Replaces the entry for the specified key only if it is 841 * currently mapped to some value. 842 * 843 * <p>The default implementation makes no guarantees about synchronization 844 * or atomicity properties of this method. Any implementation providing 845 * atomicity guarantees must override this method and document its 846 * concurrency properties. 847 * 848 * @implSpec 849 * The default implementation is equivalent to, for this {@code map}: 850 * 851 * <pre> {@code 852 * if (map.containsKey(key)) { 853 * return map.put(key, value); 854 * } else 855 * return null; 856 * }</pre> 857 * 858 * @param key key with which the specified value is associated 859 * @param value value to be associated with the specified key 860 * @return the previous value associated with the specified key, or 861 * {@code null} if there was no mapping for the key. 862 * (A {@code null} return can also indicate that the map 863 * previously associated {@code null} with the key, 864 * if the implementation supports null values.) 865 * @throws UnsupportedOperationException if the {@code put} operation 866 * is not supported by this map 867 * (<a href="Collection.html#optional-restrictions">optional</a>) 868 * @throws ClassCastException if the class of the specified key or value 869 * prevents it from being stored in this map 870 * (<a href="Collection.html#optional-restrictions">optional</a>) 871 * @throws NullPointerException if the specified key or value is null, 872 * and this map does not permit null keys or values 873 * @throws IllegalArgumentException if some property of the specified key 874 * or value prevents it from being stored in this map 875 * @since 1.8 876 */ 877 default V replace(K key, V value) { 878 return containsKey(key) ? put(key, value) : null; 879 } 880 881 /** 882 * If the specified key is not already associated with a value (or 883 * is mapped to {@code null}), attempts to compute its value using 884 * the given mapping function and enters it into this map unless 885 * {@code null}. 886 * 887 * <p>If the function returns {@code null} no mapping is recorded. If 888 * the function itself throws an (unchecked) exception, the 889 * exception is rethrown, and no mapping is recorded. The most 890 * common usage is to construct a new object serving as an initial 891 * mapped value or memoized result, as in: 892 * 893 * <pre> {@code 894 * map.computeIfAbsent(key, k -> new Value(f(k))); 895 * }</pre> 896 * 897 * <p>The default implementation makes no guarantees about synchronization 898 * or atomicity properties of this method. Any implementation providing 899 * atomicity guarantees must override this method and document its 900 * concurrency properties. In particular, all implementations of 901 * subinterface {@link java.util.concurrent.ConcurrentMap} must document 902 * whether the function is applied once atomically only if the value is not 903 * present. Any class that permits null values must document 904 * whether and how this method distinguishes absence from null mappings. 905 * 906 * @implSpec 907 * The default implementation is equivalent to the following 908 * steps for this {@code map}, then returning the current value or 909 * {@code null} if now absent: 910 * 911 * <pre> {@code 912 * if (map.get(key) == null) { 913 * V newValue = mappingFunction.apply(key); 914 * if (newValue != null) 915 * map.putIfAbsent(key, newValue); 916 * } 917 * }</pre> 918 * 919 * @param key key with which the specified value is to be associated 920 * @param mappingFunction the function to compute a value 921 * @return the current (existing or computed) value associated with 922 * the specified key, or null if the computed value is null 923 * @throws NullPointerException if the specified key is null and 924 * this map does not support null keys, or the 925 * mappingFunction is null 926 * @throws UnsupportedOperationException if the {@code put} operation 927 * is not supported by this map 928 * (<a href="Collection.html#optional-restrictions">optional</a>) 929 * @throws ClassCastException if the class of the specified key or value 930 * prevents it from being stored in this map 931 * (<a href="Collection.html#optional-restrictions">optional</a>) 932 * @since 1.8 933 */ 934 default V computeIfAbsent(K key, 935 Function<? super K, ? extends V> mappingFunction) { 936 V v, newValue; 937 return ((v = get(key)) == null && 938 (newValue = mappingFunction.apply(key)) != null && 939 (v = putIfAbsent(key, newValue)) == null) ? newValue : v; 940 } 941 942 /** 943 * If the value for the specified key is present and non-null, attempts to 944 * compute a new mapping given the key and its current mapped value. 945 * 946 * <p>If the function returns {@code null}, the mapping is removed. If the 947 * function itself throws an (unchecked) exception, the exception is 948 * rethrown, and the current mapping is left unchanged. 949 * 950 * <p>The default implementation makes no guarantees about synchronization 951 * or atomicity properties of this method. Any implementation providing 952 * atomicity guarantees must override this method and document its 953 * concurrency properties. In particular, all implementations of 954 * subinterface {@link java.util.concurrent.ConcurrentMap} must document 955 * whether the function is applied once atomically only if the value is not 956 * present. Any class that permits null values must document 957 * whether and how this method distinguishes absence from null mappings. 958 * 959 * @implSpec 960 * The default implementation is equivalent to performing the 961 * following steps for this {@code map}, then returning the 962 * current value or {@code null} if now absent: 963 * 964 * <pre> {@code 965 * if (map.get(key) != null) { 966 * V oldValue = map.get(key); 967 * V newValue = remappingFunction.apply(key, oldValue); 968 * if (newValue != null) 969 * map.replace(key, oldValue, newValue); 970 * else 971 * map.remove(key, oldValue); 972 * } 973 * }</pre> 974 * 975 * In concurrent contexts, the default implementation may retry 976 * these steps when multiple threads attempt updates. 977 * 978 * @param key key with which the specified value is to be associated 979 * @param remappingFunction the function to compute a value 980 * @return the new value associated with the specified key, or null if none 981 * @throws NullPointerException if the specified key is null and 982 * this map does not support null keys, or the 983 * remappingFunction is null 984 * @throws UnsupportedOperationException if the {@code put} operation 985 * is not supported by this map 986 * (<a href="Collection.html#optional-restrictions">optional</a>) 987 * @throws ClassCastException if the class of the specified key or value 988 * prevents it from being stored in this map 989 * (<a href="Collection.html#optional-restrictions">optional</a>) 990 * @since 1.8 991 */ 992 default V computeIfPresent(K key, 993 BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 994 V oldValue; 995 while ((oldValue = get(key)) != null) { 996 V newValue = remappingFunction.apply(key, oldValue); 997 if (newValue != null) { 998 if (replace(key, oldValue, newValue)) 999 return newValue; 1000 } else if (remove(key, oldValue)) 1001 return null; 1002 } 1003 return oldValue; 1004 } 1005 1006 /** 1007 * Attempts to compute a mapping for the specified key and its 1008 * current mapped value (or {@code null} if there is no current 1009 * mapping). For example, to either create or append a {@code 1010 * String msg} to a value mapping: 1011 * 1012 * <pre> {@code 1013 * map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre> 1014 * (Method {@link #merge merge()} is often simpler to use for such purposes.) 1015 * 1016 * <p>If the function returns {@code null}, the mapping is removed (or 1017 * remains absent if initially absent). If the function itself throws an 1018 * (unchecked) exception, the exception is rethrown, and the current mapping 1019 * is left unchanged. 1020 * 1021 * <p>The default implementation makes no guarantees about synchronization 1022 * or atomicity properties of this method. Any implementation providing 1023 * atomicity guarantees must override this method and document its 1024 * concurrency properties. In particular, all implementations of 1025 * subinterface {@link java.util.concurrent.ConcurrentMap} must document 1026 * whether the function is applied once atomically only if the value is not 1027 * present. Any class that permits null values must document 1028 * whether and how this method distinguishes absence from null mappings. 1029 * 1030 * @implSpec 1031 * The default implementation is equivalent to performing the following 1032 * steps for this {@code map}, then returning the current value or 1033 * {@code null} if absent: 1034 * 1035 * <pre> {@code 1036 * V oldValue = map.get(key); 1037 * V newValue = remappingFunction.apply(key, oldValue); 1038 * if (oldValue != null ) { 1039 * if (newValue != null) 1040 * map.replace(key, oldValue, newValue); 1041 * else 1042 * map.remove(key, oldValue); 1043 * } else { 1044 * if (newValue != null) 1045 * map.putIfAbsent(key, newValue); 1046 * else 1047 * return null; 1048 * } 1049 * }</pre> 1050 * 1051 * In concurrent contexts, the default implementation may retry 1052 * these steps when multiple threads attempt updates. 1053 * 1054 * @param key key with which the specified value is to be associated 1055 * @param remappingFunction the function to compute a value 1056 * @return the new value associated with the specified key, or null if none 1057 * @throws NullPointerException if the specified key is null and 1058 * this map does not support null keys, or the 1059 * remappingFunction is null 1060 * @throws UnsupportedOperationException if the {@code put} operation 1061 * is not supported by this map 1062 * (<a href="Collection.html#optional-restrictions">optional</a>) 1063 * @throws ClassCastException if the class of the specified key or value 1064 * prevents it from being stored in this map 1065 * (<a href="Collection.html#optional-restrictions">optional</a>) 1066 * @since 1.8 1067 */ 1068 default V compute(K key, 1069 BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 1070 V oldValue = get(key); 1071 for (;;) { 1072 V newValue = remappingFunction.apply(key, oldValue); 1073 if (newValue == null) { 1074 // delete mapping 1075 if(oldValue != null || containsKey(key)) { 1076 // something to remove 1077 if (remove(key, oldValue)) { 1078 // removed the old value as expected 1079 return null; 1080 } 1081 1082 // some other value replaced old value. try again. 1083 oldValue = get(key); 1084 } else { 1085 // nothing to do. Leave things as they were. 1086 return null; 1087 } 1088 } else { 1089 // add or replace old mapping 1090 if (oldValue != null) { 1091 // replace 1092 if (replace(key, oldValue, newValue)) { 1093 // replaced as expected. 1094 return newValue; 1095 } 1096 1097 // some other value replaced old value. try again. 1098 oldValue = get(key); 1099 } else { 1100 // add (replace if oldValue was null) 1101 if ((oldValue = putIfAbsent(key, newValue)) == null) { 1102 // replaced 1103 return newValue; 1104 } 1105 1106 // some other value replaced old value. try again. 1107 } 1108 } 1109 } 1110 } 1111 1112 /** 1113 * If the specified key is not already associated with a value or is 1114 * associated with null, associates it with the given value. 1115 * Otherwise, replaces the value with the results of the given 1116 * remapping function, or removes if the result is {@code null}. This 1117 * method may be of use when combining multiple mapped values for a key. 1118 * For example, to either create or append a {@code String msg} to a 1119 * value mapping: 1120 * 1121 * <pre> {@code 1122 * map.merge(key, msg, String::concat) 1123 * }</pre> 1124 * 1125 * <p>If the function returns {@code null}, the mapping is removed (or 1126 * remains absent if initially absent). If the function itself throws an 1127 * (unchecked) exception, the exception is rethrown, and the current mapping 1128 * is left unchanged. 1129 * 1130 * <p>The default implementation makes no guarantees about synchronization 1131 * or atomicity properties of this method. Any implementation providing 1132 * atomicity guarantees must override this method and document its 1133 * concurrency properties. In particular, all implementations of 1134 * subinterface {@link java.util.concurrent.ConcurrentMap} must document 1135 * whether the function is applied once atomically only if the value is not 1136 * present. Any class that permits null values must document 1137 * whether and how this method distinguishes absence from null mappings. 1138 * 1139 * @implSpec 1140 * The default implementation is equivalent to performing the 1141 * following steps for this {@code map}, then returning the 1142 * current value or {@code null} if absent: 1143 * 1144 * <pre> {@code 1145 * V oldValue = map.get(key); 1146 * V newValue = (oldValue == null) ? value : 1147 * remappingFunction.apply(oldValue, value); 1148 * if (newValue == null) 1149 * map.remove(key, oldValue); 1150 * else if (oldValue == null) 1151 * map.putIfAbsent(key, newValue); 1152 * else 1153 * map.replace(key, oldValue, newValue); 1154 * }</pre> 1155 * 1156 * In concurrent contexts, the default implementation may retry 1157 * these steps when multiple threads attempt updates. 1158 * 1159 * @param key key with which the specified value is to be associated 1160 * @param value the value to use if absent 1161 * @param remappingFunction the function to recompute a value if present 1162 * @return the new value associated with the specified key, or null if none 1163 * @throws UnsupportedOperationException if the {@code put} operation 1164 * is not supported by this map 1165 * (<a href="Collection.html#optional-restrictions">optional</a>) 1166 * @throws ClassCastException if the class of the specified key or value 1167 * prevents it from being stored in this map 1168 * (<a href="Collection.html#optional-restrictions">optional</a>) 1169 * @throws NullPointerException if the specified key is null and 1170 * this map does not support null keys, or the 1171 * remappingFunction is null 1172 * @since 1.8 1173 */ 1174 default V merge(K key, V value, 1175 BiFunction<? super V, ? super V, ? extends V> remappingFunction) { 1176 V oldValue = get(key); 1177 for (;;) { 1178 if (oldValue != null) { 1179 V newValue = remappingFunction.apply(oldValue, value); 1180 if (newValue != null) { 1181 if (replace(key, oldValue, newValue)) 1182 return newValue; 1183 } else if (remove(key, oldValue)) { 1184 return null; 1185 } 1186 oldValue = get(key); 1187 } else { 1188 if (value == null) { 1189 return null; 1190 } 1191 1192 if ((oldValue = putIfAbsent(key, value)) == null) { 1193 return value; 1194 } 1195 } 1196 } 1197 } 1198 }