src/share/classes/java/util/Hashtable.java

Print this page




   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.io.*;

  29 import java.util.function.BiConsumer;
  30 import java.util.function.Function;
  31 import java.util.function.BiFunction;
  32 
  33 /**
  34  * This class implements a hash table, which maps keys to values. Any
  35  * non-<code>null</code> object can be used as a key or as a value. <p>
  36  *
  37  * To successfully store and retrieve objects from a hashtable, the
  38  * objects used as keys must implement the <code>hashCode</code>
  39  * method and the <code>equals</code> method. <p>
  40  *
  41  * An instance of <code>Hashtable</code> has two parameters that affect its
  42  * performance: <i>initial capacity</i> and <i>load factor</i>.  The
  43  * <i>capacity</i> is the number of <i>buckets</i> in the hash table, and the
  44  * <i>initial capacity</i> is simply the capacity at the time the hash table
  45  * is created.  Note that the hash table is <i>open</i>: in the case of a "hash
  46  * collision", a single bucket stores multiple entries, which must be searched
  47  * sequentially.  The <i>load factor</i> is a measure of how full the hash
  48  * table is allowed to get before its capacity is automatically increased.


 202                 UNSAFE = null;
 203                 HASHSEED_OFFSET = 0;
 204             }
 205         }
 206     }
 207 
 208     /**
 209      * A randomizing value associated with this instance that is applied to
 210      * hash code of keys to make hash collisions harder to find.
 211      *
 212      * Non-final so it can be set lazily, but be sure not to set more than once.
 213      */
 214     transient final int hashSeed;
 215 
 216     /**
 217      * Return an initial value for the hashSeed, or 0 if the random seed is not
 218      * enabled.
 219      */
 220     final int initHashSeed() {
 221         if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) {
 222             return sun.misc.Hashing.randomHashSeed(this);

 223         }
 224         return 0;
 225     }
 226 
 227     private int hash(Object k) {
 228         return hashSeed ^ k.hashCode();
 229     }
 230 
 231     /**
 232      * Constructs a new, empty hashtable with the specified initial
 233      * capacity and the specified load factor.
 234      *
 235      * @param      initialCapacity   the initial capacity of the hashtable.
 236      * @param      loadFactor        the load factor of the hashtable.
 237      * @exception  IllegalArgumentException  if the initial capacity is less
 238      *             than zero, or if the load factor is nonpositive.
 239      */
 240     public Hashtable(int initialCapacity, float loadFactor) {
 241         if (initialCapacity < 0)
 242             throw new IllegalArgumentException("Illegal Capacity: "+


1189 
1190         // Write out the key/value objects from the stacked entries
1191         while (entryStack != null) {
1192             s.writeObject(entryStack.key);
1193             s.writeObject(entryStack.value);
1194             entryStack = entryStack.next;
1195         }
1196     }
1197 
1198     /**
1199      * Reconstitute the Hashtable from a stream (i.e., deserialize it).
1200      */
1201     private void readObject(java.io.ObjectInputStream s)
1202          throws IOException, ClassNotFoundException
1203     {
1204         // Read in the length, threshold, and loadfactor
1205         s.defaultReadObject();
1206 
1207         // set hashMask
1208         if (Holder.USE_HASHSEED) {

1209             Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET,
1210                     sun.misc.Hashing.randomHashSeed(this));
1211         }
1212 
1213         // Read the original length of the array and number of elements
1214         int origlength = s.readInt();
1215         int elements = s.readInt();
1216 
1217         // Compute new size with a bit of room 5% to grow but
1218         // no larger than the original size.  Make the length
1219         // odd if it's large enough, this helps distribute the entries.
1220         // Guard against the length ending up zero, that's not valid.
1221         int length = (int)(elements * loadFactor) + (elements / 20) + 3;
1222         if (length > elements && (length & 1) == 0)
1223             length--;
1224         if (origlength > 0 && length > origlength)
1225             length = origlength;
1226         table = new Entry<?,?>[length];
1227         threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
1228         count = 0;
1229 
1230         // Read the number of elements and then all the key/value objects




   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.io.*;
  29 import java.util.concurrent.ThreadLocalRandom;
  30 import java.util.function.BiConsumer;
  31 import java.util.function.Function;
  32 import java.util.function.BiFunction;
  33 
  34 /**
  35  * This class implements a hash table, which maps keys to values. Any
  36  * non-<code>null</code> object can be used as a key or as a value. <p>
  37  *
  38  * To successfully store and retrieve objects from a hashtable, the
  39  * objects used as keys must implement the <code>hashCode</code>
  40  * method and the <code>equals</code> method. <p>
  41  *
  42  * An instance of <code>Hashtable</code> has two parameters that affect its
  43  * performance: <i>initial capacity</i> and <i>load factor</i>.  The
  44  * <i>capacity</i> is the number of <i>buckets</i> in the hash table, and the
  45  * <i>initial capacity</i> is simply the capacity at the time the hash table
  46  * is created.  Note that the hash table is <i>open</i>: in the case of a "hash
  47  * collision", a single bucket stores multiple entries, which must be searched
  48  * sequentially.  The <i>load factor</i> is a measure of how full the hash
  49  * table is allowed to get before its capacity is automatically increased.


 203                 UNSAFE = null;
 204                 HASHSEED_OFFSET = 0;
 205             }
 206         }
 207     }
 208 
 209     /**
 210      * A randomizing value associated with this instance that is applied to
 211      * hash code of keys to make hash collisions harder to find.
 212      *
 213      * Non-final so it can be set lazily, but be sure not to set more than once.
 214      */
 215     transient final int hashSeed;
 216 
 217     /**
 218      * Return an initial value for the hashSeed, or 0 if the random seed is not
 219      * enabled.
 220      */
 221     final int initHashSeed() {
 222         if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) {
 223             int seed = ThreadLocalRandom.current().nextInt();
 224             return (0 != seed) ? seed : 1;
 225         }
 226         return 0;
 227     }
 228 
 229     private int hash(Object k) {
 230         return hashSeed ^ k.hashCode();
 231     }
 232 
 233     /**
 234      * Constructs a new, empty hashtable with the specified initial
 235      * capacity and the specified load factor.
 236      *
 237      * @param      initialCapacity   the initial capacity of the hashtable.
 238      * @param      loadFactor        the load factor of the hashtable.
 239      * @exception  IllegalArgumentException  if the initial capacity is less
 240      *             than zero, or if the load factor is nonpositive.
 241      */
 242     public Hashtable(int initialCapacity, float loadFactor) {
 243         if (initialCapacity < 0)
 244             throw new IllegalArgumentException("Illegal Capacity: "+


1191 
1192         // Write out the key/value objects from the stacked entries
1193         while (entryStack != null) {
1194             s.writeObject(entryStack.key);
1195             s.writeObject(entryStack.value);
1196             entryStack = entryStack.next;
1197         }
1198     }
1199 
1200     /**
1201      * Reconstitute the Hashtable from a stream (i.e., deserialize it).
1202      */
1203     private void readObject(java.io.ObjectInputStream s)
1204          throws IOException, ClassNotFoundException
1205     {
1206         // Read in the length, threshold, and loadfactor
1207         s.defaultReadObject();
1208 
1209         // set hashMask
1210         if (Holder.USE_HASHSEED) {            
1211             int seed = ThreadLocalRandom.current().nextInt();
1212             Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET,
1213                                           0 != seed ? seed : 1);
1214         }
1215 
1216         // Read the original length of the array and number of elements
1217         int origlength = s.readInt();
1218         int elements = s.readInt();
1219 
1220         // Compute new size with a bit of room 5% to grow but
1221         // no larger than the original size.  Make the length
1222         // odd if it's large enough, this helps distribute the entries.
1223         // Guard against the length ending up zero, that's not valid.
1224         int length = (int)(elements * loadFactor) + (elements / 20) + 3;
1225         if (length > elements && (length & 1) == 0)
1226             length--;
1227         if (origlength > 0 && length > origlength)
1228             length = origlength;
1229         table = new Entry<?,?>[length];
1230         threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
1231         count = 0;
1232 
1233         // Read the number of elements and then all the key/value objects