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 /**
29 * An object that maps keys to values. A map cannot contain duplicate keys;
30 * each key can map to at most one value.
31 *
32 * <p>This interface takes the place of the <tt>Dictionary</tt> class, which
33 * was a totally abstract class rather than an interface.
34 *
35 * <p>The <tt>Map</tt> interface provides three <i>collection views</i>, which
36 * allow a map's contents to be viewed as a set of keys, collection of values,
37 * or set of key-value mappings. The <i>order</i> of a map is defined as
38 * the order in which the iterators on the map's collection views return their
39 * elements. Some map implementations, like the <tt>TreeMap</tt> class, make
40 * specific guarantees as to their order; others, like the <tt>HashMap</tt>
41 * class, do not.
42 *
43 * <p>Note: great care must be exercised if mutable objects are used as map
44 * keys. The behavior of a map is not specified if the value of an object is
45 * changed in a manner that affects <tt>equals</tt> comparisons while the
46 * object is a key in the map. A special case of this prohibition is that it
47 * is not permissible for a map to contain itself as a key. While it is
98 * for example, by first comparing the hash codes of the two keys. (The
99 * {@link Object#hashCode()} specification guarantees that two objects with
100 * unequal hash codes cannot be equal.) More generally, implementations of
101 * the various Collections Framework interfaces are free to take advantage of
102 * the specified behavior of underlying {@link Object} methods wherever the
103 * implementor deems it appropriate.
104 *
105 * @param <K> the type of keys maintained by this map
106 * @param <V> the type of mapped values
107 *
108 * @author Josh Bloch
109 * @see HashMap
110 * @see TreeMap
111 * @see Hashtable
112 * @see SortedMap
113 * @see Collection
114 * @see Set
115 * @since 1.2
116 */
117 public interface Map<K,V> {
118 // Query Operations
119
120 /**
121 * Returns the number of key-value mappings in this map. If the
122 * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
123 * <tt>Integer.MAX_VALUE</tt>.
124 *
125 * @return the number of key-value mappings in this map
126 */
127 int size();
128
129 /**
130 * Returns <tt>true</tt> if this map contains no key-value mappings.
131 *
132 * @return <tt>true</tt> if this map contains no key-value mappings
133 */
134 boolean isEmpty();
135
136 /**
137 * Returns <tt>true</tt> if this map contains a mapping for the specified
458 * @param o object to be compared for equality with this map
459 * @return <tt>true</tt> if the specified object is equal to this map
460 */
461 boolean equals(Object o);
462
463 /**
464 * Returns the hash code value for this map. The hash code of a map is
465 * defined to be the sum of the hash codes of each entry in the map's
466 * <tt>entrySet()</tt> view. This ensures that <tt>m1.equals(m2)</tt>
467 * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two maps
468 * <tt>m1</tt> and <tt>m2</tt>, as required by the general contract of
469 * {@link Object#hashCode}.
470 *
471 * @return the hash code value for this map
472 * @see Map.Entry#hashCode()
473 * @see Object#equals(Object)
474 * @see #equals(Object)
475 */
476 int hashCode();
477
478 }
|
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
32 /**
33 * An object that maps keys to values. A map cannot contain duplicate keys;
34 * each key can map to at most one value.
35 *
36 * <p>This interface takes the place of the <tt>Dictionary</tt> class, which
37 * was a totally abstract class rather than an interface.
38 *
39 * <p>The <tt>Map</tt> interface provides three <i>collection views</i>, which
40 * allow a map's contents to be viewed as a set of keys, collection of values,
41 * or set of key-value mappings. The <i>order</i> of a map is defined as
42 * the order in which the iterators on the map's collection views return their
43 * elements. Some map implementations, like the <tt>TreeMap</tt> class, make
44 * specific guarantees as to their order; others, like the <tt>HashMap</tt>
45 * class, do not.
46 *
47 * <p>Note: great care must be exercised if mutable objects are used as map
48 * keys. The behavior of a map is not specified if the value of an object is
49 * changed in a manner that affects <tt>equals</tt> comparisons while the
50 * object is a key in the map. A special case of this prohibition is that it
51 * is not permissible for a map to contain itself as a key. While it is
102 * for example, by first comparing the hash codes of the two keys. (The
103 * {@link Object#hashCode()} specification guarantees that two objects with
104 * unequal hash codes cannot be equal.) More generally, implementations of
105 * the various Collections Framework interfaces are free to take advantage of
106 * the specified behavior of underlying {@link Object} methods wherever the
107 * implementor deems it appropriate.
108 *
109 * @param <K> the type of keys maintained by this map
110 * @param <V> the type of mapped values
111 *
112 * @author Josh Bloch
113 * @see HashMap
114 * @see TreeMap
115 * @see Hashtable
116 * @see SortedMap
117 * @see Collection
118 * @see Set
119 * @since 1.2
120 */
121 public interface Map<K,V> {
122
123 // Query Operations
124
125 /**
126 * Returns the number of key-value mappings in this map. If the
127 * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
128 * <tt>Integer.MAX_VALUE</tt>.
129 *
130 * @return the number of key-value mappings in this map
131 */
132 int size();
133
134 /**
135 * Returns <tt>true</tt> if this map contains no key-value mappings.
136 *
137 * @return <tt>true</tt> if this map contains no key-value mappings
138 */
139 boolean isEmpty();
140
141 /**
142 * Returns <tt>true</tt> if this map contains a mapping for the specified
463 * @param o object to be compared for equality with this map
464 * @return <tt>true</tt> if the specified object is equal to this map
465 */
466 boolean equals(Object o);
467
468 /**
469 * Returns the hash code value for this map. The hash code of a map is
470 * defined to be the sum of the hash codes of each entry in the map's
471 * <tt>entrySet()</tt> view. This ensures that <tt>m1.equals(m2)</tt>
472 * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two maps
473 * <tt>m1</tt> and <tt>m2</tt>, as required by the general contract of
474 * {@link Object#hashCode}.
475 *
476 * @return the hash code value for this map
477 * @see Map.Entry#hashCode()
478 * @see Object#equals(Object)
479 * @see #equals(Object)
480 */
481 int hashCode();
482
483 // Defaultable methods
484
485 /**
486 * Execute the specified {@code BiBlock} with the key and value of
487 * each entry in this map.
488 *
489 * @param block the {@code BiBlock} to which entries will be applied
490 */
491 default void forEach(BiConsumer<? super K, ? super V> block) {
492 Objects.requireNonNull(block);
493 for (Map.Entry<K, V> entry : entrySet()) {
494 block.accept(entry.getKey(), entry.getValue());
495 }
496 }
497
498 /**
499 * Apply the specified function to each entry in this map, replacing
500 * each entry's value with the result of calling the function's
501 * {@code Function#map} method with the current entry's key and value.
502 *
503 * @param function the function to apply to each entry
504 */
505 default void replaceAll(BiFunction<K, V, V> function) {
506 Objects.requireNonNull(function);
507 final Iterator<Map.Entry<K, V>> entries = entrySet().iterator();
508 while (entries.hasNext()) {
509 final Map.Entry<K, V> entry = entries.next();
510 entry.setValue(function.apply(entry.getKey(), entry.getValue()));
511 }
512 }
513
514 /**
515 * If the specified key is not already associated with a value,
516 * associates it with the given value and returns {@code null},
517 * else returns the current value.
518 *
519 * <p>The default implementation is equivalent to, for this {@code
520 * map}:
521 *
522 * <pre> {@code
523 * if (!map.containsKey(key))
524 * return map.put(key, value);
525 * else
526 * return map.get(key);}</pre>
527 *
528 * <p>The default implementation makes no guarantees about
529 * synchronization or atomicity properties of this method. Any
530 * class overriding this method must specify its concurrency
531 * properties. In particular, all implementations of
532 * subinterface {@link java.util.concurrent.ConcurrentMap}
533 * must ensure that this operation is performed atomically.
534 *
535 * @param key key with which the specified value is to be associated
536 * @param value value to be associated with the specified key
537 * @return the previous value associated with the specified key, or
538 * <tt>null</tt> if there was no mapping for the key.
539 * (A <tt>null</tt> return can also indicate that the map
540 * previously associated <tt>null</tt> with the key,
541 * if the implementation supports null values.)
542 * @throws UnsupportedOperationException if the <tt>put</tt> operation
543 * is not supported by this map
544 * @throws ClassCastException if the class of the specified key or value
545 * prevents it from being stored in this map
546 * @throws NullPointerException if the specified key or value is null,
547 * and this map does not permit null keys or values
548 * @throws IllegalArgumentException if some property of the specified key
549 * or value prevents it from being stored in this map
550 */
551 default V putIfAbsent(K key, V value) {
552 return containsKey(key) ? get(key) : put(key, value);
553 }
554
555 /**
556 * Removes the entry for the specified key only if it is currently
557 * mapped to the specified value.
558 *
559 * <p>The default implementation is equivalent to, for this {@code map}:
560 *
561 * <pre> {@code
562 * if (map.containsKey(key) && map.get(key).equals(value)) {
563 * map.remove(key);
564 * return true;
565 * } else
566 * return false;}</pre>
567 *
568 * <p>The default implementation makes no guarantees about
569 * synchronization or atomicity properties of this method. Any
570 * class overriding this method must specify its concurrency
571 * properties. In particular, all implementations of
572 * subinterface {@link java.util.concurrent.ConcurrentMap}
573 * must ensure that this operation is performed atomically.
574 *
575 * @param key key with which the specified value is associated
576 * @param value value expected to be associated with the specified key
577 * @return <tt>true</tt> if the value was removed
578 * @throws UnsupportedOperationException if the <tt>remove</tt> operation
579 * is not supported by this map
580 * @throws ClassCastException if the key or value is of an inappropriate
581 * type for this map
582 * (<a href="Collection.html#optional-restrictions">optional</a>)
583 * @throws NullPointerException if the specified key or value is null,
584 * and this map does not permit null keys or values
585 * (<a href="Collection.html#optional-restrictions">optional</a>)
586 */
587 default boolean remove(Object key, Object value) {
588 if (!containsKey(key) || !get(key).equals(value))
589 return false;
590 remove(key);
591 return true;
592 }
593
594 /**
595 * Replaces the entry for the specified key only if currently
596 * mapped to the specified value.
597 *
598 * <p>The default implementation is equivalent to, for this {@code map}:
599 *
600 * <pre> {@code
601 * if (map.containsKey(key) && map.get(key).equals(oldValue)) {
602 * map.put(key, newValue);
603 * return true;
604 * } else
605 * return false;}</pre>
606 *
607 * <p>The default implementation makes no guarantees about
608 * synchronization or atomicity properties of this method. Any
609 * class overriding this method must specify its concurrency
610 * properties. In particular, all implementations of
611 * subinterface {@link java.util.concurrent.ConcurrentMap}
612 * must ensure that this operation is performed atomically.
613 *
614 * @param key key with which the specified value is associated
615 * @param oldValue value expected to be associated with the specified key
616 * @param newValue value to be associated with the specified key
617 * @return <tt>true</tt> if the value was replaced
618 * @throws UnsupportedOperationException if the <tt>put</tt> operation
619 * is not supported by this map
620 * @throws ClassCastException if the class of a specified key or value
621 * prevents it from being stored in this map
622 * @throws NullPointerException if a specified key or value is null,
623 * and this map does not permit null keys or values
624 * @throws IllegalArgumentException if some property of a specified key
625 * or value prevents it from being stored in this map
626 */
627 default boolean replace(K key, V oldValue, V newValue) {
628 if (!containsKey(key) || !get(key).equals(oldValue))
629 return false;
630 put(key, newValue);
631 return true;
632 }
633
634 /**
635 * Replaces the entry for the specified key only if it is
636 * currently mapped to some value.
637 *
638 * <p>The default implementation is equivalent to, for this {@code map}:
639 *
640 * <pre> {@code
641 * if (map.containsKey(key)) {
642 * return map.put(key, value);
643 * } else
644 * return null;}</pre>
645 *
646 * <p>The default implementation makes no guarantees about
647 * synchronization or atomicity properties of this method. Any
648 * class overriding this method must specify its concurrency
649 * properties. In particular, all implementations of
650 * subinterface {@link java.util.concurrent.ConcurrentMap}
651 * must ensure that this operation is performed atomically.
652 *
653 * @param key key with which the specified value is associated
654 * @param value value to be associated with the specified key
655 * @return the previous value associated with the specified key, or
656 * <tt>null</tt> if there was no mapping for the key.
657 * (A <tt>null</tt> return can also indicate that the map
658 * previously associated <tt>null</tt> with the key,
659 * if the implementation supports null values.)
660 * @throws UnsupportedOperationException if the <tt>put</tt> operation
661 * is not supported by this map
662 * @throws ClassCastException if the class of the specified key or value
663 * prevents it from being stored in this map
664 * @throws NullPointerException if the specified key or value is null,
665 * and this map does not permit null keys or values
666 * @throws IllegalArgumentException if some property of the specified key
667 * or value prevents it from being stored in this map
668 */
669 default V replace(K key, V value) {
670 return containsKey(key) ? put(key, value) : null;
671 }
672
673 /**
674 * If the specified key is not already associated with a value (or
675 * is mapped to {@code null}), attempts to compute its value using
676 * the given mapping function and enters it into this map unless
677 * {@code null}.
678 *
679 * <p>The default implementation is equivalent to the following
680 * steps for this {@code map}, then returning the current value or
681 * {@code null} if now absent:
682 *
683 * <pre> {@code
684 * if (map.get(key) == null) {
685 * V newValue = mappingFunction.apply(key);
686 * if (newValue != null)
687 * map.putIfAbsent(key, newValue);
688 * }}</pre>
689 *
690 * If the function returns {@code null} no mapping is recorded. If
691 * the function itself throws an (unchecked) exception, the
692 * exception is rethrown, and no mapping is recorded. The most
693 * common usage is to construct a new object serving as an initial
694 * mapped value or memoized result, as in:
695 *
696 * <pre> {@code
697 * map.computeIfAbsent(key, k -> new Value(f(k)));}</pre>
698 *
699 * <p>The default implementation makes no guarantees about
700 * synchronization or atomicity properties of this method or the
701 * application of the mapping function. Any class overriding this
702 * method must specify its concurrency properties. In particular,
703 * all implementations of subinterface {@link
704 * java.util.concurrent.ConcurrentMap} must document whether the
705 * function is applied once atomically only if the value is not
706 * present. Any class that permits null values must document
707 * whether and how this method distinguishes absence from null
708 * mappings.
709 *
710 * @param key key with which the specified value is to be associated
711 * @param mappingFunction the function to compute a value
712 * @return the current (existing or computed) value associated with
713 * the specified key, or null if the computed value is null
714 * @throws NullPointerException if the specified key is null and
715 * this map does not support null keys, or the
716 * mappingFunction is null
717 * @throws UnsupportedOperationException if the <tt>put</tt> operation
718 * is not supported by this map
719 * @throws ClassCastException if the class of the specified key or value
720 * prevents it from being stored in this map
721 * @throws RuntimeException or Error if the mappingFunction does so,
722 * in which case the mapping is left unestablished
723 */
724 default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
725 V v, newValue;
726 return ((v = get(key)) == null &&
727 (newValue = mappingFunction.apply(key)) != null &&
728 (v = putIfAbsent(key, newValue)) == null) ? newValue : v;
729 }
730
731 /**
732 * If the value for the specified key is present and non-null,
733 * attempts to compute a new mapping given the key and its current
734 * mapped value.
735 *
736 * <p>The default implementation is equivalent to performing the
737 * following steps for this {@code map}, then returning the
738 * current value or {@code null} if now absent:
739 *
740 * <pre> {@code
741 * if (map.get(key) != null) {
742 * V oldValue = map.get(key);
743 * V newValue = remappingFunction.apply(key, oldValue);
744 * if (newValue != null)
745 * map.replace(key, oldValue, newValue);
746 * else
747 * map.remove(key, oldValue);
748 * }}</pre>
749 *
750 * In concurrent contexts, the default implementation may retry
751 * these steps when multiple threads attempt updates. If the
752 * function returns {@code null}, the mapping is removed (or
753 * remains absent if initially absent). If the function itself
754 * throws an (unchecked) exception, the exception is rethrown, and
755 * the current mapping is left unchanged.
756 *
757 * <p>The default implementation makes no guarantees about
758 * synchronization or atomicity properties of this method or the
759 * application of the remapping function. Any class overriding
760 * this method must specify its concurrency properties. In
761 * particular, all implementations of subinterface {@link
762 * java.util.concurrent.ConcurrentMap} must document whether the
763 * function is applied once atomically only if the value is
764 * present. Any class that permits null values must document
765 * whether and how this method distinguishes absence from null
766 * mappings.
767 *
768 * @param key key with which the specified value is to be associated
769 * @param remappingFunction the function to compute a value
770 * @return the new value associated with the specified key, or null if none
771 * @throws NullPointerException if the specified key is null and
772 * this map does not support null keys, or the
773 * remappingFunction is null
774 * @throws UnsupportedOperationException if the <tt>put</tt> operation
775 * is not supported by this map
776 * @throws ClassCastException if the class of the specified key or value
777 * prevents it from being stored in this map
778 * @throws RuntimeException or Error if the remappingFunction does so,
779 * in which case the mapping is unchanged
780 */
781 default V computeIfPresent(K key,
782 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
783 V v;
784 while ((v = get(key)) != null) {
785 V newValue = remappingFunction.apply(key, v);
786 if (newValue != null) {
787 if (replace(key, v, newValue))
788 return newValue;
789 }
790 else if (remove(key, v))
791 return null;
792 }
793 return v;
794 }
795
796 /**
797 * Attempts to compute a mapping for the specified key and its
798 * current mapped value (or {@code null} if there is no current
799 * mapping). For example, to either create or append a {@code
800 * String msg} to a value mapping:
801 *
802 * <pre> {@code
803 * map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre>
804 * (Method {@link #merge} is often simpler to use for such purposes.)
805 *
806 * <p>The default implementation is equivalent to
807 * performing the following steps for this {@code map}, then
808 * returning the current value or {@code null} if absent:
809 *
810 * <pre> {@code
811 * V oldValue = map.get(key);
812 * V newValue = remappingFunction.apply(key, oldValue);
813 * if (newValue != null)
814 * map.replace(key, oldValue, newValue);
815 * else
816 * map.remove(key, oldValue);
817 * }</pre>
818 *
819 * In concurrent contexts, the default implementation may retry
820 * these steps when multiple threads attempt updates. If the
821 * function returns {@code null}, the mapping is removed (or
822 * remains absent if initially absent). If the function itself
823 * throws an (unchecked) exception, the exception is rethrown, and
824 * the current mapping is left unchanged.
825 *
826 * <p>The default implementation makes no guarantees about
827 * synchronization or atomicity properties of this method or the
828 * application of the remapping function. Any class overriding
829 * this method must specify its concurrency properties. In
830 * particular, all implementations of subinterface {@link
831 * java.util.concurrent.ConcurrentMap} must document whether the
832 * function is applied exactly once atomically. Any class that
833 * permits null values must document whether and how this method
834 * distinguishes absence from null mappings.
835 *
836 * @param key key with which the specified value is to be associated
837 * @param remappingFunction the function to compute a value
838 * @return the new value associated with the specified key, or null if none
839 * @throws NullPointerException if the specified key is null and
840 * this map does not support null keys, or the
841 * remappingFunction is null
842 * @throws UnsupportedOperationException if the <tt>put</tt> operation
843 * is not supported by this map
844 * @throws ClassCastException if the class of the specified key or value
845 * prevents it from being stored in this map
846 * @throws RuntimeException or Error if the remappingFunction does so,
847 * in which case the mapping is unchanged
848 */
849 default V compute(K key,
850 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
851 for (;;) {
852 V oldValue = get(key);
853 V newValue = remappingFunction.apply(key, oldValue);
854 if (newValue != null) {
855 if (replace(key, oldValue, newValue))
856 return newValue;
857 }
858 else if (remove(key, oldValue))
859 return null;
860 }
861 }
862
863 /**
864 * If the specified key is not already associated with a
865 * (non-null) value, associates it with the given value.
866 * Otherwise, replaces the value with the results of the given
867 * remapping function, or removes if {@code null}. This method may
868 * be of use when combining multiple mapped values for a key. For
869 * example. to either create or append a {@code String msg} to a
870 * value mapping:
871 *
872 * <pre> {@code
873 * map.merge(key, msg, String::concat)}</pre>
874 *
875 * <p>The default implementation is equivalent to performing the
876 * following steps for this {@code map}, then returning the
877 * current value or {@code null} if absent:
878 *
879 * <pre> {@code
880 * V oldValue = map.get(key);
881 * V newValue = (oldValue == null) ? value :
882 * remappingFunction.apply(oldValue, value);
883 * if (newValue == null)
884 * map.remove(key, oldValue);
885 * else if (oldValue == null)
886 * map.putIfAbsent(key, newValue);
887 * else
888 * map.replace(key, oldValue, newValue);
889 * }</pre>
890 *
891 * In concurrent contexts, the default implementation may retry
892 * these steps when multiple threads attempt updates. If the
893 * function returns {@code null}, the mapping is removed (or
894 * remains absent if initially absent). If the function itself
895 * throws an (unchecked) exception, the exception is rethrown, and
896 * the current mapping is left unchanged.
897 *
898 * <p>The default implementation makes no guarantees about
899 * synchronization or atomicity properties of this method or the
900 * application of the remapping function. Any class overriding
901 * this method must specify its concurrency properties. In
902 * particular, all implementations of subinterface {@link
903 * java.util.concurrent.ConcurrentMap} must document whether the
904 * function is applied exactly once atomically. Any class that
905 * permits null values must document whether and how this method
906 * distinguishes absence from null mappings.
907 *
908 * @param key key with which the specified value is to be associated
909 * @param value the value to use if absent
910 * @param remappingFunction the function to recompute a value if present
911 * @return the new value associated with the specified key, or null if none
912 * @throws NullPointerException if the specified key is null and
913 * this map does not support null keys, or the
914 * remappingFunction is null
915 * @throws RuntimeException or Error if the remappingFunction does so,
916 * in which case the mapping is unchanged
917 */
918 default V merge(K key, V value,
919 BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
920 for (;;) {
921 V oldValue, newValue;
922 if ((oldValue = get(key)) == null) {
923 if (value == null || putIfAbsent(key, value) == null)
924 return value;
925 }
926 else if ((newValue = remappingFunction.apply(oldValue, value)) != null) {
927 if (replace(key, oldValue, newValue))
928 return newValue;
929 }
930 else if (remove(key, oldValue))
931 return null;
932 }
933 }
934 }
|