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 * @param key key with which the specified value is associated 808 * @param oldValue value expected to be associated with the specified key 809 * @param newValue value to be associated with the specified key 810 * @return {@code true} if the value was replaced 811 * @throws UnsupportedOperationException if the {@code put} operation 812 * is not supported by this map 813 * (<a href="Collection.html#optional-restrictions">optional</a>) 814 * @throws ClassCastException if the class of a specified key or value 815 * prevents it from being stored in this map 816 * @throws NullPointerException if a specified key or value is null, 817 * and this map does not permit null keys or values 818 * @throws IllegalArgumentException if some property of a specified key 819 * or value prevents it from being stored in this map 820 * @since 1.8 821 */ 822 default boolean replace(K key, V oldValue, V newValue) { 823 Object curValue = get(key); 824 if (!Objects.equals(curValue, oldValue) || 825 (curValue == null && !containsKey(key))) { 826 return false; 827 } 828 put(key, newValue); 829 return true; 830 } 831 832 /** 833 * Replaces the entry for the specified key only if it is 834 * currently mapped to some value. 835 * 836 * <p>The default implementation makes no guarantees about synchronization 837 * or atomicity properties of this method. Any implementation providing 838 * atomicity guarantees must override this method and document its 839 * concurrency properties. 840 * 841 * @implSpec 842 * The default implementation is equivalent to, for this {@code map}: 843 * 844 * <pre> {@code 845 * if (map.containsKey(key)) { 846 * return map.put(key, value); 847 * } else 848 * return null; 849 * }</pre> 850 * 851 * @param key key with which the specified value is associated 852 * @param value value to be associated with the specified key 853 * @return the previous value associated with the specified key, or 854 * {@code null} if there was no mapping for the key. 855 * (A {@code null} return can also indicate that the map 856 * previously associated {@code null} with the key, 857 * if the implementation supports null values.) 858 * @throws UnsupportedOperationException if the {@code put} operation 859 * is not supported by this map 860 * (<a href="Collection.html#optional-restrictions">optional</a>) 861 * @throws ClassCastException if the class of the specified key or value 862 * prevents it from being stored in this map 863 * (<a href="Collection.html#optional-restrictions">optional</a>) 864 * @throws NullPointerException if the specified key or value is null, 865 * and this map does not permit null keys or values 866 * @throws IllegalArgumentException if some property of the specified key 867 * or value prevents it from being stored in this map 868 * @since 1.8 869 */ 870 default V replace(K key, V value) { 871 return containsKey(key) ? put(key, value) : null; 872 } 873 874 /** 875 * If the specified key is not already associated with a value (or 876 * is mapped to {@code null}), attempts to compute its value using 877 * the given mapping function and enters it into this map unless 878 * {@code null}. 879 * 880 * <p>If the function returns {@code null} no mapping is recorded. If 881 * the function itself throws an (unchecked) exception, the 882 * exception is rethrown, and no mapping is recorded. The most 883 * common usage is to construct a new object serving as an initial 884 * mapped value or memoized result, as in: 885 * 886 * <pre> {@code 887 * map.computeIfAbsent(key, k -> new Value(f(k))); 888 * }</pre> 889 * 890 * <p>The default implementation makes no guarantees about synchronization 891 * or atomicity properties of this method. Any implementation providing 892 * atomicity guarantees must override this method and document its 893 * concurrency properties. In particular, all implementations of 894 * subinterface {@link java.util.concurrent.ConcurrentMap} must document 895 * whether the function is applied once atomically only if the value is not 896 * present. Any class that permits null values must document 897 * whether and how this method distinguishes absence from null mappings. 898 * 899 * @implSpec 900 * The default implementation is equivalent to the following 901 * steps for this {@code map}, then returning the current value or 902 * {@code null} if now absent: 903 * 904 * <pre> {@code 905 * if (map.get(key) == null) { 906 * V newValue = mappingFunction.apply(key); 907 * if (newValue != null) 908 * map.putIfAbsent(key, newValue); 909 * } 910 * }</pre> 911 * 912 * @param key key with which the specified value is to be associated 913 * @param mappingFunction the function to compute a value 914 * @return the current (existing or computed) value associated with 915 * the specified key, or null if the computed value is null 916 * @throws NullPointerException if the specified key is null and 917 * this map does not support null keys, or the 918 * mappingFunction is null 919 * @throws UnsupportedOperationException if the {@code put} operation 920 * is not supported by this map 921 * (<a href="Collection.html#optional-restrictions">optional</a>) 922 * @throws ClassCastException if the class of the specified key or value 923 * prevents it from being stored in this map 924 * (<a href="Collection.html#optional-restrictions">optional</a>) 925 * @since 1.8 926 */ 927 default V computeIfAbsent(K key, 928 Function<? super K, ? extends V> mappingFunction) { 929 V v, newValue; 930 return ((v = get(key)) == null && 931 (newValue = mappingFunction.apply(key)) != null && 932 (v = putIfAbsent(key, newValue)) == null) ? newValue : v; 933 } 934 935 /** 936 * If the value for the specified key is present and non-null, attempts to 937 * compute a new mapping given the key and its current mapped value. 938 * 939 * <p>If the function returns {@code null}, the mapping is removed. If the 940 * function itself throws an (unchecked) exception, the exception is 941 * rethrown, and the current mapping is left unchanged. 942 * 943 * <p>The default implementation makes no guarantees about synchronization 944 * or atomicity properties of this method. Any implementation providing 945 * atomicity guarantees must override this method and document its 946 * concurrency properties. In particular, all implementations of 947 * subinterface {@link java.util.concurrent.ConcurrentMap} must document 948 * whether the function is applied once atomically only if the value is not 949 * present. Any class that permits null values must document 950 * whether and how this method distinguishes absence from null mappings. 951 * 952 * @implSpec 953 * The default implementation is equivalent to performing the 954 * following steps for this {@code map}, then returning the 955 * current value or {@code null} if now absent: 956 * 957 * <pre> {@code 958 * if (map.get(key) != null) { 959 * V oldValue = map.get(key); 960 * V newValue = remappingFunction.apply(key, oldValue); 961 * if (newValue != null) 962 * map.replace(key, oldValue, newValue); 963 * else 964 * map.remove(key, oldValue); 965 * } 966 * }</pre> 967 * 968 * In concurrent contexts, the default implementation may retry 969 * these steps when multiple threads attempt updates. 970 * 971 * @param key key with which the specified value is to be associated 972 * @param remappingFunction the function to compute a value 973 * @return the new value associated with the specified key, or null if none 974 * @throws NullPointerException if the specified key is null and 975 * this map does not support null keys, or the 976 * remappingFunction is null 977 * @throws UnsupportedOperationException if the {@code put} operation 978 * is not supported by this map 979 * (<a href="Collection.html#optional-restrictions">optional</a>) 980 * @throws ClassCastException if the class of the specified key or value 981 * prevents it from being stored in this map 982 * (<a href="Collection.html#optional-restrictions">optional</a>) 983 * @since 1.8 984 */ 985 default V computeIfPresent(K key, 986 BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 987 V oldValue; 988 while ((oldValue = get(key)) != null) { 989 V newValue = remappingFunction.apply(key, oldValue); 990 if (newValue != null) { 991 if (replace(key, oldValue, newValue)) 992 return newValue; 993 } else if (remove(key, oldValue)) 994 return null; 995 } 996 return oldValue; 997 } 998 999 /** 1000 * Attempts to compute a mapping for the specified key and its 1001 * current mapped value (or {@code null} if there is no current 1002 * mapping). For example, to either create or append a {@code 1003 * String msg} to a value mapping: 1004 * 1005 * <pre> {@code 1006 * map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre> 1007 * (Method {@link #merge merge()} is often simpler to use for such purposes.) 1008 * 1009 * <p>If the function returns {@code null}, the mapping is removed (or 1010 * remains absent if initially absent). If the function itself throws an 1011 * (unchecked) exception, the exception is rethrown, and the current mapping 1012 * is left unchanged. 1013 * 1014 * <p>The default implementation makes no guarantees about synchronization 1015 * or atomicity properties of this method. Any implementation providing 1016 * atomicity guarantees must override this method and document its 1017 * concurrency properties. In particular, all implementations of 1018 * subinterface {@link java.util.concurrent.ConcurrentMap} must document 1019 * whether the function is applied once atomically only if the value is not 1020 * present. Any class that permits null values must document 1021 * whether and how this method distinguishes absence from null mappings. 1022 * 1023 * @implSpec 1024 * The default implementation is equivalent to performing the following 1025 * steps for this {@code map}, then returning the current value or 1026 * {@code null} if absent: 1027 * 1028 * <pre> {@code 1029 * V oldValue = map.get(key); 1030 * V newValue = remappingFunction.apply(key, oldValue); 1031 * if (oldValue != null ) { 1032 * if (newValue != null) 1033 * map.replace(key, oldValue, newValue); 1034 * else 1035 * map.remove(key, oldValue); 1036 * } else { 1037 * if (newValue != null) 1038 * map.putIfAbsent(key, newValue); 1039 * else 1040 * return null; 1041 * } 1042 * }</pre> 1043 * 1044 * In concurrent contexts, the default implementation may retry 1045 * these steps when multiple threads attempt updates. 1046 * 1047 * @param key key with which the specified value is to be associated 1048 * @param remappingFunction the function to compute a value 1049 * @return the new value associated with the specified key, or null if none 1050 * @throws NullPointerException if the specified key is null and 1051 * this map does not support null keys, or the 1052 * remappingFunction is null 1053 * @throws UnsupportedOperationException if the {@code put} operation 1054 * is not supported by this map 1055 * (<a href="Collection.html#optional-restrictions">optional</a>) 1056 * @throws ClassCastException if the class of the specified key or value 1057 * prevents it from being stored in this map 1058 * (<a href="Collection.html#optional-restrictions">optional</a>) 1059 * @since 1.8 1060 */ 1061 default V compute(K key, 1062 BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 1063 V oldValue = get(key); 1064 for (;;) { 1065 V newValue = remappingFunction.apply(key, oldValue); 1066 if (newValue == null) { 1067 // delete mapping 1068 if(oldValue != null || containsKey(key)) { 1069 // something to remove 1070 if (remove(key, oldValue)) { 1071 // removed the old value as expected 1072 return null; 1073 } 1074 1075 // some other value replaced old value. try again. 1076 oldValue = get(key); 1077 } else { 1078 // nothing to do. Leave things as they were. 1079 return null; 1080 } 1081 } else { 1082 // add or replace old mapping 1083 if (oldValue != null) { 1084 // replace 1085 if (replace(key, oldValue, newValue)) { 1086 // replaced as expected. 1087 return newValue; 1088 } 1089 1090 // some other value replaced old value. try again. 1091 oldValue = get(key); 1092 } else { 1093 // add (replace if oldValue was null) 1094 if ((oldValue = putIfAbsent(key, newValue)) == null) { 1095 // replaced 1096 return newValue; 1097 } 1098 1099 // some other value replaced old value. try again. 1100 } 1101 } 1102 } 1103 } 1104 1105 /** 1106 * If the specified key is not already associated with a value or is 1107 * associated with null, associates it with the given value. 1108 * Otherwise, replaces the value with the results of the given 1109 * remapping function, or removes if the result is {@code null}. This 1110 * method may be of use when combining multiple mapped values for a key. 1111 * For example, to either create or append a {@code String msg} to a 1112 * value mapping: 1113 * 1114 * <pre> {@code 1115 * map.merge(key, msg, String::concat) 1116 * }</pre> 1117 * 1118 * <p>If the function returns {@code null}, the mapping is removed (or 1119 * remains absent if initially absent). If the function itself throws an 1120 * (unchecked) exception, the exception is rethrown, and the current mapping 1121 * is left unchanged. 1122 * 1123 * <p>The default implementation makes no guarantees about synchronization 1124 * or atomicity properties of this method. Any implementation providing 1125 * atomicity guarantees must override this method and document its 1126 * concurrency properties. In particular, all implementations of 1127 * subinterface {@link java.util.concurrent.ConcurrentMap} must document 1128 * whether the function is applied once atomically only if the value is not 1129 * present. Any class that permits null values must document 1130 * whether and how this method distinguishes absence from null mappings. 1131 * 1132 * @implSpec 1133 * The default implementation is equivalent to performing the 1134 * following steps for this {@code map}, then returning the 1135 * current value or {@code null} if absent: 1136 * 1137 * <pre> {@code 1138 * V oldValue = map.get(key); 1139 * V newValue = (oldValue == null) ? value : 1140 * remappingFunction.apply(oldValue, value); 1141 * if (newValue == null) 1142 * map.remove(key, oldValue); 1143 * else if (oldValue == null) 1144 * map.putIfAbsent(key, newValue); 1145 * else 1146 * map.replace(key, oldValue, newValue); 1147 * }</pre> 1148 * 1149 * In concurrent contexts, the default implementation may retry 1150 * these steps when multiple threads attempt updates. 1151 * 1152 * @param key key with which the specified value is to be associated 1153 * @param value the value to use if absent 1154 * @param remappingFunction the function to recompute a value if present 1155 * @return the new value associated with the specified key, or null if none 1156 * @throws UnsupportedOperationException if the {@code put} operation 1157 * is not supported by this map 1158 * (<a href="Collection.html#optional-restrictions">optional</a>) 1159 * @throws ClassCastException if the class of the specified key or value 1160 * prevents it from being stored in this map 1161 * (<a href="Collection.html#optional-restrictions">optional</a>) 1162 * @throws NullPointerException if the specified key is null and 1163 * this map does not support null keys, or the 1164 * remappingFunction is null 1165 * @since 1.8 1166 */ 1167 default V merge(K key, V value, 1168 BiFunction<? super V, ? super V, ? extends V> remappingFunction) { 1169 V oldValue = get(key); 1170 for (;;) { 1171 if (oldValue != null) { 1172 V newValue = remappingFunction.apply(oldValue, value); 1173 if (newValue != null) { 1174 if (replace(key, oldValue, newValue)) 1175 return newValue; 1176 } else if (remove(key, oldValue)) { 1177 return null; 1178 } 1179 oldValue = get(key); 1180 } else { 1181 if (value == null) { 1182 return null; 1183 } 1184 1185 if ((oldValue = putIfAbsent(key, value)) == null) { 1186 return value; 1187 } 1188 } 1189 } 1190 } 1191 }