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 BiConsumer} with the key and value of
487 * each entry in this map.
488 *
489 * @param block the {@code BiConsumer} 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 * {@link BiFunction#apply(Object, Object) BiFunction.apply(K key, V, value)}
502 * method with the current entry's key and value.
503 *
504 * @param function the function to apply to each entry
505 */
506 default void replaceAll(BiFunction<K, V, V> function) {
507 Objects.requireNonNull(function);
508 for (Map.Entry<K, V> entry : entrySet()) {
509 entry.setValue(function.apply(entry.getKey(), entry.getValue()));
510 }
511 }
512
513 /**
514 * If the specified key is not already associated with a value,
515 * associates it with the given value and returns {@code null},
516 * else returns the current value.
517 *
518 * <p>The default implementation is equivalent to, for this {@code
519 * map}:
520 *
521 * <pre> {@code
522 * if (!map.containsKey(key))
523 * return map.put(key, value);
524 * else
525 * return map.get(key);}</pre>
526 *
527 * <p>The default implementation makes no guarantees about
528 * synchronization or atomicity properties of this method. Any
529 * class overriding this method must specify its concurrency
530 * properties. In particular, all implementations of
531 * subinterface {@link java.util.concurrent.ConcurrentMap}
532 * must ensure that this operation is performed atomically.
533 *
534 * @param key key with which the specified value is to be associated
535 * @param value value to be associated with the specified key
536 * @return the previous value associated with the specified key, or
537 * <tt>null</tt> if there was no mapping for the key.
538 * (A <tt>null</tt> return can also indicate that the map
539 * previously associated <tt>null</tt> with the key,
540 * if the implementation supports null values.)
541 * @throws UnsupportedOperationException if the <tt>put</tt> operation
542 * is not supported by this map
543 * @throws ClassCastException if the class of the specified key or value
544 * prevents it from being stored in this map
545 * @throws NullPointerException if the specified key or value is null,
546 * and this map does not permit null keys or values
547 * @throws IllegalArgumentException if some property of the specified key
548 * or value prevents it from being stored in this map
549 */
550 default V putIfAbsent(K key, V value) {
551 return containsKey(key) ? get(key) : put(key, value);
552 }
553
554 /**
555 * Removes the entry for the specified key only if it is currently
556 * mapped to the specified value.
557 *
558 * <p>The default implementation is equivalent to, for this {@code map}:
559 *
560 * <pre> {@code
561 * if (map.containsKey(key) && map.get(key).equals(value)) {
562 * map.remove(key);
563 * return true;
564 * } else
565 * return false;}</pre>
566 *
567 * <p>The default implementation makes no guarantees about
568 * synchronization or atomicity properties of this method. Any
569 * class overriding this method must specify its concurrency
570 * properties. In particular, all implementations of
571 * subinterface {@link java.util.concurrent.ConcurrentMap}
572 * must ensure that this operation is performed atomically.
573 *
574 * @param key key with which the specified value is associated
575 * @param value value expected to be associated with the specified key
576 * @return <tt>true</tt> if the value was removed
577 * @throws UnsupportedOperationException if the <tt>remove</tt> operation
578 * is not supported by this map
579 * @throws ClassCastException if the key or value is of an inappropriate
580 * type for this map
581 * (<a href="Collection.html#optional-restrictions">optional</a>)
582 * @throws NullPointerException if the specified key or value is null,
583 * and this map does not permit null keys or values
584 * (<a href="Collection.html#optional-restrictions">optional</a>)
585 */
586 default boolean remove(Object key, Object value) {
587 if (!containsKey(key) || !get(key).equals(value))
588 return false;
589 remove(key);
590 return true;
591 }
592
593 /**
594 * Replaces the entry for the specified key only if currently
595 * mapped to the specified value.
596 *
597 * <p>The default implementation is equivalent to, for this {@code map}:
598 *
599 * <pre> {@code
600 * if (map.containsKey(key) && map.get(key).equals(oldValue)) {
601 * map.put(key, newValue);
602 * return true;
603 * } else
604 * return false;}</pre>
605 *
606 * <p>The default implementation makes no guarantees about
607 * synchronization or atomicity properties of this method. Any
608 * class overriding this method must specify its concurrency
609 * properties. In particular, all implementations of
610 * subinterface {@link java.util.concurrent.ConcurrentMap}
611 * must ensure that this operation is performed atomically.
612 *
613 * @param key key with which the specified value is associated
614 * @param oldValue value expected to be associated with the specified key
615 * @param newValue value to be associated with the specified key
616 * @return <tt>true</tt> if the value was replaced
617 * @throws UnsupportedOperationException if the <tt>put</tt> operation
618 * is not supported by this map
619 * @throws ClassCastException if the class of a specified key or value
620 * prevents it from being stored in this map
621 * @throws NullPointerException if a specified key or value is null,
622 * and this map does not permit null keys or values
623 * @throws IllegalArgumentException if some property of a specified key
624 * or value prevents it from being stored in this map
625 */
626 default boolean replace(K key, V oldValue, V newValue) {
627 if (!containsKey(key) || !get(key).equals(oldValue))
628 return false;
629 put(key, newValue);
630 return true;
631 }
632
633 /**
634 * Replaces the entry for the specified key only if it is
635 * currently mapped to some value.
636 *
637 * <p>The default implementation is equivalent to, for this {@code map}:
638 *
639 * <pre> {@code
640 * if (map.containsKey(key)) {
641 * return map.put(key, value);
642 * } else
643 * return null;}</pre>
644 *
645 * <p>The default implementation makes no guarantees about
646 * synchronization or atomicity properties of this method. Any
647 * class overriding this method must specify its concurrency
648 * properties. In particular, all implementations of
649 * subinterface {@link java.util.concurrent.ConcurrentMap}
650 * must ensure that this operation is performed atomically.
651 *
652 * @param key key with which the specified value is associated
653 * @param value value to be associated with the specified key
654 * @return the previous value associated with the specified key, or
655 * <tt>null</tt> if there was no mapping for the key.
656 * (A <tt>null</tt> return can also indicate that the map
657 * previously associated <tt>null</tt> with the key,
658 * if the implementation supports null values.)
659 * @throws UnsupportedOperationException if the <tt>put</tt> operation
660 * is not supported by this map
661 * @throws ClassCastException if the class of the specified key or value
662 * prevents it from being stored in this map
663 * @throws NullPointerException if the specified key or value is null,
664 * and this map does not permit null keys or values
665 * @throws IllegalArgumentException if some property of the specified key
666 * or value prevents it from being stored in this map
667 */
668 default V replace(K key, V value) {
669 return containsKey(key) ? put(key, value) : null;
670 }
671
672 /**
673 * If the specified key is not already associated with a value (or
674 * is mapped to {@code null}), attempts to compute its value using
675 * the given mapping function and enters it into this map unless
676 * {@code null}.
677 *
678 * <p>The default implementation is equivalent to the following
679 * steps for this {@code map}, then returning the current value or
680 * {@code null} if now absent:
681 *
682 * <pre> {@code
683 * if (map.get(key) == null) {
684 * V newValue = mappingFunction.apply(key);
685 * if (newValue != null)
686 * map.putIfAbsent(key, newValue);
687 * }}</pre>
688 *
689 * If the function returns {@code null} no mapping is recorded. If
690 * the function itself throws an (unchecked) exception, the
691 * exception is rethrown, and no mapping is recorded. The most
692 * common usage is to construct a new object serving as an initial
693 * mapped value or memoized result, as in:
694 *
695 * <pre> {@code
696 * map.computeIfAbsent(key, k -> new Value(f(k)));}</pre>
697 *
698 * <p>The default implementation makes no guarantees about
699 * synchronization or atomicity properties of this method or the
700 * application of the mapping function. Any class overriding this
701 * method must specify its concurrency properties. In particular,
702 * all implementations of subinterface {@link
703 * java.util.concurrent.ConcurrentMap} must document whether the
704 * function is applied once atomically only if the value is not
705 * present. Any class that permits null values must document
706 * whether and how this method distinguishes absence from null
707 * mappings.
708 *
709 * @param key key with which the specified value is to be associated
710 * @param mappingFunction the function to compute a value
711 * @return the current (existing or computed) value associated with
712 * the specified key, or null if the computed value is null
713 * @throws NullPointerException if the specified key is null and
714 * this map does not support null keys, or the
715 * mappingFunction is null
716 * @throws UnsupportedOperationException if the <tt>put</tt> operation
717 * is not supported by this map
718 * @throws ClassCastException if the class of the specified key or value
719 * prevents it from being stored in this map
720 * @throws RuntimeException or Error if the mappingFunction does so,
721 * in which case the mapping is left unestablished
722 */
723 default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
724 V v, newValue;
725 return ((v = get(key)) == null &&
726 (newValue = mappingFunction.apply(key)) != null &&
727 (v = putIfAbsent(key, newValue)) == null) ? newValue : v;
728 }
729
730 /**
731 * If the value for the specified key is present and non-null,
732 * attempts to compute a new mapping given the key and its current
733 * mapped value.
734 *
735 * <p>The default implementation is equivalent to performing the
736 * following steps for this {@code map}, then returning the
737 * current value or {@code null} if now absent:
738 *
739 * <pre> {@code
740 * if (map.get(key) != null) {
741 * V oldValue = map.get(key);
742 * V newValue = remappingFunction.apply(key, oldValue);
743 * if (newValue != null)
744 * map.replace(key, oldValue, newValue);
745 * else
746 * map.remove(key, oldValue);
747 * }}</pre>
748 *
749 * In concurrent contexts, the default implementation may retry
750 * these steps when multiple threads attempt updates. If the
751 * function returns {@code null}, the mapping is removed (or
752 * remains absent if initially absent). If the function itself
753 * throws an (unchecked) exception, the exception is rethrown, and
754 * the current mapping is left unchanged.
755 *
756 * <p>The default implementation makes no guarantees about
757 * synchronization or atomicity properties of this method or the
758 * application of the remapping function. Any class overriding
759 * this method must specify its concurrency properties. In
760 * particular, all implementations of subinterface {@link
761 * java.util.concurrent.ConcurrentMap} must document whether the
762 * function is applied once atomically only if the value is
763 * present. Any class that permits null values must document
764 * whether and how this method distinguishes absence from null
765 * mappings.
766 *
767 * @param key key with which the specified value is to be associated
768 * @param remappingFunction the function to compute a value
769 * @return the new value associated with the specified key, or null if none
770 * @throws NullPointerException if the specified key is null and
771 * this map does not support null keys, or the
772 * remappingFunction is null
773 * @throws UnsupportedOperationException if the <tt>put</tt> operation
774 * is not supported by this map
775 * @throws ClassCastException if the class of the specified key or value
776 * prevents it from being stored in this map
777 * @throws RuntimeException or Error if the remappingFunction does so,
778 * in which case the mapping is unchanged
779 */
780 default V computeIfPresent(K key,
781 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
782 V v;
783 while ((v = get(key)) != null) {
784 V newValue = remappingFunction.apply(key, v);
785 if (newValue != null) {
786 if (replace(key, v, newValue))
787 return newValue;
788 }
789 else if (remove(key, v))
790 return null;
791 }
792 return v;
793 }
794
795 /**
796 * Attempts to compute a mapping for the specified key and its
797 * current mapped value (or {@code null} if there is no current
798 * mapping). For example, to either create or append a {@code
799 * String msg} to a value mapping:
800 *
801 * <pre> {@code
802 * map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre>
803 * (Method {@link #merge} is often simpler to use for such purposes.)
804 *
805 * <p>The default implementation is equivalent to
806 * performing the following steps for this {@code map}, then
807 * returning the current value or {@code null} if absent:
808 *
809 * <pre> {@code
810 * V oldValue = map.get(key);
811 * V newValue = remappingFunction.apply(key, oldValue);
812 * if (newValue != null)
813 * map.replace(key, oldValue, newValue);
814 * else
815 * map.remove(key, oldValue);
816 * }</pre>
817 *
818 * In concurrent contexts, the default implementation may retry
819 * these steps when multiple threads attempt updates. If the
820 * function returns {@code null}, the mapping is removed (or
821 * remains absent if initially absent). If the function itself
822 * throws an (unchecked) exception, the exception is rethrown, and
823 * the current mapping is left unchanged.
824 *
825 * <p>The default implementation makes no guarantees about
826 * synchronization or atomicity properties of this method or the
827 * application of the remapping function. Any class overriding
828 * this method must specify its concurrency properties. In
829 * particular, all implementations of subinterface {@link
830 * java.util.concurrent.ConcurrentMap} must document whether the
831 * function is applied exactly once atomically. Any class that
832 * permits null values must document whether and how this method
833 * distinguishes absence from null mappings.
834 *
835 * @param key key with which the specified value is to be associated
836 * @param remappingFunction the function to compute a value
837 * @return the new value associated with the specified key, or null if none
838 * @throws NullPointerException if the specified key is null and
839 * this map does not support null keys, or the
840 * remappingFunction is null
841 * @throws UnsupportedOperationException if the <tt>put</tt> operation
842 * is not supported by this map
843 * @throws ClassCastException if the class of the specified key or value
844 * prevents it from being stored in this map
845 * @throws RuntimeException or Error if the remappingFunction does so,
846 * in which case the mapping is unchanged
847 */
848 default V compute(K key,
849 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
850 for (;;) {
851 V oldValue = get(key);
852 V newValue = remappingFunction.apply(key, oldValue);
853 if (newValue != null) {
854 if (replace(key, oldValue, newValue))
855 return newValue;
856 }
857 else if (remove(key, oldValue))
858 return null;
859 }
860 }
861
862 /**
863 * If the specified key is not already associated with a
864 * (non-null) value, associates it with the given value.
865 * Otherwise, replaces the value with the results of the given
866 * remapping function, or removes if {@code null}. This method may
867 * be of use when combining multiple mapped values for a key. For
868 * example. to either create or append a {@code String msg} to a
869 * value mapping:
870 *
871 * <pre> {@code
872 * map.merge(key, msg, String::concat)}</pre>
873 *
874 * <p>The default implementation is equivalent to performing the
875 * following steps for this {@code map}, then returning the
876 * current value or {@code null} if absent:
877 *
878 * <pre> {@code
879 * V oldValue = map.get(key);
880 * V newValue = (oldValue == null) ? value :
881 * remappingFunction.apply(oldValue, value);
882 * if (newValue == null)
883 * map.remove(key, oldValue);
884 * else if (oldValue == null)
885 * map.putIfAbsent(key, newValue);
886 * else
887 * map.replace(key, oldValue, newValue);
888 * }</pre>
889 *
890 * In concurrent contexts, the default implementation may retry
891 * these steps when multiple threads attempt updates. If the
892 * function returns {@code null}, the mapping is removed (or
893 * remains absent if initially absent). If the function itself
894 * throws an (unchecked) exception, the exception is rethrown, and
895 * the current mapping is left unchanged.
896 *
897 * <p>The default implementation makes no guarantees about
898 * synchronization or atomicity properties of this method or the
899 * application of the remapping function. Any class overriding
900 * this method must specify its concurrency properties. In
901 * particular, all implementations of subinterface {@link
902 * java.util.concurrent.ConcurrentMap} must document whether the
903 * function is applied exactly once atomically. Any class that
904 * permits null values must document whether and how this method
905 * distinguishes absence from null mappings.
906 *
907 * @param key key with which the specified value is to be associated
908 * @param value the value to use if absent
909 * @param remappingFunction the function to recompute a value if present
910 * @return the new value associated with the specified key, or null if none
911 * @throws NullPointerException if the specified key is null and
912 * this map does not support null keys, or the
913 * remappingFunction is null
914 * @throws RuntimeException or Error if the remappingFunction does so,
915 * in which case the mapping is unchanged
916 */
917 default V merge(K key, V value,
918 BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
919 for (;;) {
920 V oldValue, newValue;
921 if ((oldValue = get(key)) == null) {
922 if (value == null || putIfAbsent(key, value) == null)
923 return value;
924 }
925 else if ((newValue = remappingFunction.apply(oldValue, value)) != null) {
926 if (replace(key, oldValue, newValue))
927 return newValue;
928 }
929 else if (remove(key, oldValue))
930 return null;
931 }
932 }
933 }
|