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