src/share/classes/java/util/WeakHashMap.java

Print this page
rev 7313 : 8016446: Improve forEach/replaceAll for Map, HashMap, Hashtable, IdentityHashMap, WeakHashMap, TreeMap
Reviewed-by: forax, duigou
Contributed-by: Mike Duigou <mike.duigou@oracle.com>, Remi Forax <forax@univ-mlv.fr>


  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                 Object key = entry.get();
1050                 if (key != null) {
1051                     action.accept((K) WeakHashMap.unmaskNull(key), entry.value);
1052                 }
1053                 entry = entry.next;
1054 
1055                 if (expectedModCount != modCount) {
1056                     throw new ConcurrentModificationException();
1057                 }
1058             }
1059         }
1060     }
1061 
1062     @Override
1063     public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
1064         Objects.requireNonNull(function);
1065         int expectedModCount = modCount;
1066 
1067         Entry<K,V>[] tab = getTable();;
1068         for(Entry<K,V> entry : tab) {
1069             while(entry != null) {
1070                 Object key = entry.get();
1071                 if (key != null) {
1072                     entry.value = function.apply((K) WeakHashMap.unmaskNull(key), entry.value);
1073                 }
1074                 entry = entry.next;
1075             }
1076 
1077             if (expectedModCount != modCount) {
1078                 throw new ConcurrentModificationException();
1079             }
1080         }
1081     }
1082 
1083     /**
1084      * Similar form as other hash Spliterators, but skips dead
1085      * elements.
1086      */
1087     static class WeakHashMapSpliterator<K,V> {
1088         final WeakHashMap<K,V> map;
1089         WeakHashMap.Entry<K,V> current; // current node
1090         int index;             // current index, modified on advance/split
1091         int fence;             // -1 until first use; then one past last index
1092         int est;               // size estimate
1093         int expectedModCount;  // for comodification checks
1094 
1095         WeakHashMapSpliterator(WeakHashMap<K,V> m, int origin,
1096                                int fence, int est,
1097                                int expectedModCount) {
1098             this.map = m;
1099             this.index = origin;