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.lang.ref.WeakReference;
29 import java.lang.ref.ReferenceQueue;
30 import java.util.concurrent.ThreadLocalRandom;
31 import java.util.function.Consumer;
32
33
34 /**
35 * Hash table based implementation of the <tt>Map</tt> interface, with
36 * <em>weak keys</em>.
37 * An entry in a <tt>WeakHashMap</tt> will automatically be removed when
38 * its key is no longer in ordinary use. More precisely, the presence of a
39 * mapping for a given key will not prevent the key from being discarded by the
40 * garbage collector, that is, made finalizable, finalized, and then reclaimed.
41 * When a key has been discarded its entry is effectively removed from the map,
42 * so this class behaves somewhat differently from other <tt>Map</tt>
43 * implementations.
44 *
45 * <p> Both null values and the null key are supported. This class has
46 * performance characteristics similar to those of the <tt>HashMap</tt>
47 * class, and has the same efficiency parameters of <em>initial capacity</em>
48 * and <em>load factor</em>.
49 *
50 * <p> Like most collection classes, this class is not synchronized.
1016 WeakHashMap.this.clear();
1017 }
1018
1019 private List<Map.Entry<K,V>> deepCopy() {
1020 List<Map.Entry<K,V>> list = new ArrayList<>(size());
1021 for (Map.Entry<K,V> e : this)
1022 list.add(new AbstractMap.SimpleEntry<>(e));
1023 return list;
1024 }
1025
1026 public Object[] toArray() {
1027 return deepCopy().toArray();
1028 }
1029
1030 public <T> T[] toArray(T[] a) {
1031 return deepCopy().toArray(a);
1032 }
1033
1034 public Spliterator<Map.Entry<K,V>> spliterator() {
1035 return new EntrySpliterator<>(WeakHashMap.this, 0, -1, 0, 0);
1036 }
1037 }
1038
1039 /**
1040 * Similar form as other hash Spliterators, but skips dead
1041 * elements.
1042 */
1043 static class WeakHashMapSpliterator<K,V> {
1044 final WeakHashMap<K,V> map;
1045 WeakHashMap.Entry<K,V> current; // current node
1046 int index; // current index, modified on advance/split
1047 int fence; // -1 until first use; then one past last index
1048 int est; // size estimate
1049 int expectedModCount; // for comodification checks
1050
1051 WeakHashMapSpliterator(WeakHashMap<K,V> m, int origin,
1052 int fence, int est,
1053 int expectedModCount) {
1054 this.map = m;
1055 this.index = origin;
|
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.lang.ref.WeakReference;
29 import java.lang.ref.ReferenceQueue;
30 import java.util.concurrent.ThreadLocalRandom;
31 import java.util.function.BiConsumer;
32 import java.util.function.BiFunction;
33 import java.util.function.Consumer;
34
35
36 /**
37 * Hash table based implementation of the <tt>Map</tt> interface, with
38 * <em>weak keys</em>.
39 * An entry in a <tt>WeakHashMap</tt> will automatically be removed when
40 * its key is no longer in ordinary use. More precisely, the presence of a
41 * mapping for a given key will not prevent the key from being discarded by the
42 * garbage collector, that is, made finalizable, finalized, and then reclaimed.
43 * When a key has been discarded its entry is effectively removed from the map,
44 * so this class behaves somewhat differently from other <tt>Map</tt>
45 * implementations.
46 *
47 * <p> Both null values and the null key are supported. This class has
48 * performance characteristics similar to those of the <tt>HashMap</tt>
49 * class, and has the same efficiency parameters of <em>initial capacity</em>
50 * and <em>load factor</em>.
51 *
52 * <p> Like most collection classes, this class is not synchronized.
1018 WeakHashMap.this.clear();
1019 }
1020
1021 private List<Map.Entry<K,V>> deepCopy() {
1022 List<Map.Entry<K,V>> list = new ArrayList<>(size());
1023 for (Map.Entry<K,V> e : this)
1024 list.add(new AbstractMap.SimpleEntry<>(e));
1025 return list;
1026 }
1027
1028 public Object[] toArray() {
1029 return deepCopy().toArray();
1030 }
1031
1032 public <T> T[] toArray(T[] a) {
1033 return deepCopy().toArray(a);
1034 }
1035
1036 public Spliterator<Map.Entry<K,V>> spliterator() {
1037 return new EntrySpliterator<>(WeakHashMap.this, 0, -1, 0, 0);
1038 }
1039 }
1040
1041 @Override
1042 public void forEach(BiConsumer<? super K, ? super V> action) {
1043 Objects.requireNonNull(action);
1044 int expectedModCount = modCount;
1045
1046 Entry<K,V>[] tab = getTable();
1047 for(Entry<K,V> entry : tab) {
1048 while(entry != null) {
1049 if (expectedModCount != modCount)
1050 throw new ConcurrentModificationException();
1051
1052 Object key = entry.get();
1053 if (key != null) {
1054 action.accept((K) WeakHashMap.unmaskNull(key), entry.value);
1055 }
1056 entry = entry.next;
1057 }
1058 }
1059 }
1060
1061 @Override
1062 public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
1063 Objects.requireNonNull(function);
1064 int expectedModCount = modCount;
1065
1066 Entry<K,V>[] tab = getTable();;
1067 for(Entry<K,V> entry : tab) {
1068 while(entry != null) {
1069 if (expectedModCount != modCount)
1070 throw new ConcurrentModificationException();
1071
1072 Object key = entry.get();
1073 if (key != null) {
1074 entry.value = function.apply((K) WeakHashMap.unmaskNull(key), entry.value);
1075 }
1076 entry = entry.next;
1077 }
1078 }
1079 }
1080
1081 /**
1082 * Similar form as other hash Spliterators, but skips dead
1083 * elements.
1084 */
1085 static class WeakHashMapSpliterator<K,V> {
1086 final WeakHashMap<K,V> map;
1087 WeakHashMap.Entry<K,V> current; // current node
1088 int index; // current index, modified on advance/split
1089 int fence; // -1 until first use; then one past last index
1090 int est; // size estimate
1091 int expectedModCount; // for comodification checks
1092
1093 WeakHashMapSpliterator(WeakHashMap<K,V> m, int origin,
1094 int fence, int est,
1095 int expectedModCount) {
1096 this.map = m;
1097 this.index = origin;
|