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