Home | History | Annotate | Download | only in util
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 // BEGIN android-note
     19 // Completely different implementation from harmony.  Runs much faster.
     20 // BEGIN android-note
     21 
     22 package java.util;
     23 
     24 import java.io.IOException;
     25 import java.io.InvalidObjectException;
     26 import java.io.ObjectInputStream;
     27 import java.io.ObjectOutputStream;
     28 import java.io.ObjectStreamField;
     29 import java.io.Serializable;
     30 
     31 /**
     32  * Hashtable is a synchronized implementation of {@link Map}. All optional operations are supported.
     33  *
     34  * <p>Neither keys nor values can be null. (Use {@code HashMap} or {@code LinkedHashMap} if you
     35  * need null keys or values.)
     36  *
     37  * @param <K> the type of keys maintained by this map
     38  * @param <V> the type of mapped values
     39  * @see HashMap
     40  */
     41 public class Hashtable<K, V> extends Dictionary<K, V>
     42         implements Map<K, V>, Cloneable, Serializable {
     43     /**
     44      * Min capacity (other than zero) for a Hashtable. Must be a power of two
     45      * greater than 1 (and less than 1 << 30).
     46      */
     47     private static final int MINIMUM_CAPACITY = 4;
     48 
     49     /**
     50      * Max capacity for a Hashtable. Must be a power of two >= MINIMUM_CAPACITY.
     51      */
     52     private static final int MAXIMUM_CAPACITY = 1 << 30;
     53 
     54     /**
     55      * An empty table shared by all zero-capacity maps (typically from default
     56      * constructor). It is never written to, and replaced on first put. Its size
     57      * is set to half the minimum, so that the first resize will create a
     58      * minimum-sized table.
     59      */
     60     private static final Entry[] EMPTY_TABLE
     61             = new HashtableEntry[MINIMUM_CAPACITY >>> 1];
     62 
     63     /**
     64      * The default load factor. Note that this implementation ignores the
     65      * load factor, but cannot do away with it entirely because it's
     66      * mentioned in the API.
     67      *
     68      * <p>Note that this constant has no impact on the behavior of the program,
     69      * but it is emitted as part of the serialized form. The load factor of
     70      * .75 is hardwired into the program, which uses cheap shifts in place of
     71      * expensive division.
     72      */
     73     private static final float DEFAULT_LOAD_FACTOR = .75F;
     74 
     75     /**
     76      * The hash table.
     77      */
     78     private transient HashtableEntry<K, V>[] table;
     79 
     80     /**
     81      * The number of mappings in this hash map.
     82      */
     83     private transient int size;
     84 
     85     /**
     86      * Incremented by "structural modifications" to allow (best effort)
     87      * detection of concurrent modification.
     88      */
     89     private transient int modCount;
     90 
     91     /**
     92      * The table is rehashed when its size exceeds this threshold.
     93      * The value of this field is generally .75 * capacity, except when
     94      * the capacity is zero, as described in the EMPTY_TABLE declaration
     95      * above.
     96      */
     97     private transient int threshold;
     98 
     99     // Views - lazily initialized
    100     private transient Set<K> keySet;
    101     private transient Set<Entry<K, V>> entrySet;
    102     private transient Collection<V> values;
    103 
    104     /**
    105      * Constructs a new {@code Hashtable} using the default capacity and load
    106      * factor.
    107      */
    108     @SuppressWarnings("unchecked")
    109     public Hashtable() {
    110         table = (HashtableEntry<K, V>[]) EMPTY_TABLE;
    111         threshold = -1; // Forces first put invocation to replace EMPTY_TABLE
    112     }
    113 
    114     /**
    115      * Constructs a new {@code Hashtable} using the specified capacity and the
    116      * default load factor.
    117      *
    118      * @param capacity
    119      *            the initial capacity.
    120      */
    121     public Hashtable(int capacity) {
    122         if (capacity < 0) {
    123             throw new IllegalArgumentException("Capacity: " + capacity);
    124         }
    125 
    126         if (capacity == 0) {
    127             @SuppressWarnings("unchecked")
    128             HashtableEntry<K, V>[] tab = (HashtableEntry<K, V>[]) EMPTY_TABLE;
    129             table = tab;
    130             threshold = -1; // Forces first put() to replace EMPTY_TABLE
    131             return;
    132         }
    133 
    134         if (capacity < MINIMUM_CAPACITY) {
    135             capacity = MINIMUM_CAPACITY;
    136         } else if (capacity > MAXIMUM_CAPACITY) {
    137             capacity = MAXIMUM_CAPACITY;
    138         } else {
    139             capacity = roundUpToPowerOfTwo(capacity);
    140         }
    141         makeTable(capacity);
    142     }
    143 
    144     /**
    145      * Constructs a new {@code Hashtable} using the specified capacity and load
    146      * factor.
    147      *
    148      * @param capacity
    149      *            the initial capacity.
    150      * @param loadFactor
    151      *            the initial load factor.
    152      */
    153     public Hashtable(int capacity, float loadFactor) {
    154         this(capacity);
    155 
    156         if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
    157             throw new IllegalArgumentException("Load factor: " + loadFactor);
    158         }
    159 
    160         /*
    161          * Note that this implementation ignores loadFactor; it always uses
    162          * a load factor of 3/4. This simplifies the code and generally
    163          * improves performance.
    164          */
    165     }
    166 
    167     /**
    168      * Constructs a new instance of {@code Hashtable} containing the mappings
    169      * from the specified map.
    170      *
    171      * @param map
    172      *            the mappings to add.
    173      */
    174     public Hashtable(Map<? extends K, ? extends V> map) {
    175         this(capacityForInitSize(map.size()));
    176         constructorPutAll(map);
    177     }
    178 
    179     /**
    180      * Inserts all of the elements of map into this Hashtable in a manner
    181      * suitable for use by constructors and pseudo-constructors (i.e., clone,
    182      * readObject).
    183      */
    184     private void constructorPutAll(Map<? extends K, ? extends V> map) {
    185         for (Entry<? extends K, ? extends V> e : map.entrySet()) {
    186             constructorPut(e.getKey(), e.getValue());
    187         }
    188     }
    189 
    190     /**
    191      * Returns an appropriate capacity for the specified initial size. Does
    192      * not round the result up to a power of two; the caller must do this!
    193      * The returned value will be between 0 and MAXIMUM_CAPACITY (inclusive).
    194      */
    195     private static int capacityForInitSize(int size) {
    196         int result = (size >> 1) + size; // Multiply by 3/2 to allow for growth
    197 
    198         // boolean expr is equivalent to result >= 0 && result<MAXIMUM_CAPACITY
    199         return (result & ~(MAXIMUM_CAPACITY-1))==0 ? result : MAXIMUM_CAPACITY;
    200     }
    201 
    202     /**
    203      * Returns a new {@code Hashtable} with the same key/value pairs, capacity
    204      * and load factor.
    205      *
    206      * @return a shallow copy of this {@code Hashtable}.
    207      * @see java.lang.Cloneable
    208      */
    209     @SuppressWarnings("unchecked")
    210     @Override public synchronized Object clone() {
    211         /*
    212          * This could be made more efficient. It unnecessarily hashes all of
    213          * the elements in the map.
    214          */
    215         Hashtable<K, V> result;
    216         try {
    217             result = (Hashtable<K, V>) super.clone();
    218         } catch (CloneNotSupportedException e) {
    219             throw new AssertionError(e);
    220         }
    221 
    222         // Restore clone to empty state, retaining our capacity and threshold
    223         result.makeTable(table.length);
    224         result.size = 0;
    225         result.keySet = null;
    226         result.entrySet = null;
    227         result.values = null;
    228 
    229         result.constructorPutAll(this);
    230         return result;
    231     }
    232 
    233     /**
    234      * Returns true if this {@code Hashtable} has no key/value pairs.
    235      *
    236      * @return {@code true} if this {@code Hashtable} has no key/value pairs,
    237      *         {@code false} otherwise.
    238      * @see #size
    239      */
    240     public synchronized boolean isEmpty() {
    241         return size == 0;
    242     }
    243 
    244     /**
    245      * Returns the number of key/value pairs in this {@code Hashtable}.
    246      *
    247      * @return the number of key/value pairs in this {@code Hashtable}.
    248      * @see #elements
    249      * @see #keys
    250      */
    251     public synchronized int size() {
    252         return size;
    253     }
    254 
    255     /**
    256      * Returns the value associated with the specified key in this
    257      * {@code Hashtable}.
    258      *
    259      * @param key
    260      *            the key of the value returned.
    261      * @return the value associated with the specified key, or {@code null} if
    262      *         the specified key does not exist.
    263      * @see #put
    264      */
    265     public synchronized V get(Object key) {
    266         // Doug Lea's supplemental secondaryHash function (inlined)
    267         int hash = key.hashCode();
    268         hash ^= (hash >>> 20) ^ (hash >>> 12);
    269         hash ^= (hash >>> 7) ^ (hash >>> 4);
    270 
    271         HashtableEntry<K, V>[] tab = table;
    272         for (HashtableEntry<K, V> e = tab[hash & (tab.length - 1)];
    273                 e != null; e = e.next) {
    274             K eKey = e.key;
    275             if (eKey == key || (e.hash == hash && key.equals(eKey))) {
    276                 return e.value;
    277             }
    278         }
    279         return null;
    280     }
    281 
    282     /**
    283      * Returns true if this {@code Hashtable} contains the specified object as a
    284      * key of one of the key/value pairs.
    285      *
    286      * @param key
    287      *            the object to look for as a key in this {@code Hashtable}.
    288      * @return {@code true} if object is a key in this {@code Hashtable},
    289      *         {@code false} otherwise.
    290      * @see #contains
    291      * @see java.lang.Object#equals
    292      */
    293     public synchronized boolean containsKey(Object key) {
    294         // Doug Lea's supplemental secondaryHash function (inlined)
    295         int hash = key.hashCode();
    296         hash ^= (hash >>> 20) ^ (hash >>> 12);
    297         hash ^= (hash >>> 7) ^ (hash >>> 4);
    298 
    299         HashtableEntry<K, V>[] tab = table;
    300         for (HashtableEntry<K, V> e = tab[hash & (tab.length - 1)];
    301                 e != null; e = e.next) {
    302             K eKey = e.key;
    303             if (eKey == key || (e.hash == hash && key.equals(eKey))) {
    304                 return true;
    305             }
    306         }
    307         return false;
    308     }
    309 
    310     /**
    311      * Searches this {@code Hashtable} for the specified value.
    312      *
    313      * @param value
    314      *            the object to search for.
    315      * @return {@code true} if {@code value} is a value of this
    316      *         {@code Hashtable}, {@code false} otherwise.
    317      */
    318     public synchronized boolean containsValue(Object value) {
    319         if (value == null) {
    320             throw new NullPointerException();
    321         }
    322 
    323         HashtableEntry[] tab = table;
    324         int len = tab.length;
    325 
    326         for (int i = 0; i < len; i++) {
    327             for (HashtableEntry e = tab[i]; e != null; e = e.next) {
    328                 if (value.equals(e.value)) {
    329                     return true;
    330                 }
    331             }
    332         }
    333         return false;
    334     }
    335 
    336     /**
    337      * Returns true if this {@code Hashtable} contains the specified object as
    338      * the value of at least one of the key/value pairs.
    339      *
    340      * @param value
    341      *            the object to look for as a value in this {@code Hashtable}.
    342      * @return {@code true} if object is a value in this {@code Hashtable},
    343      *         {@code false} otherwise.
    344      * @see #containsKey
    345      * @see java.lang.Object#equals
    346      */
    347     public boolean contains(Object value) {
    348         return containsValue(value);
    349     }
    350 
    351     /**
    352      * Associate the specified value with the specified key in this
    353      * {@code Hashtable}. If the key already exists, the old value is replaced.
    354      * The key and value cannot be null.
    355      *
    356      * @param key
    357      *            the key to add.
    358      * @param value
    359      *            the value to add.
    360      * @return the old value associated with the specified key, or {@code null}
    361      *         if the key did not exist.
    362      * @see #elements
    363      * @see #get
    364      * @see #keys
    365      * @see java.lang.Object#equals
    366      */
    367     public synchronized V put(K key, V value) {
    368         if (value == null) {
    369             throw new NullPointerException();
    370         }
    371         int hash = secondaryHash(key.hashCode());
    372         HashtableEntry<K, V>[] tab = table;
    373         int index = hash & (tab.length - 1);
    374         HashtableEntry<K, V> first = tab[index];
    375         for (HashtableEntry<K, V> e = first; e != null; e = e.next) {
    376             if (e.hash == hash && key.equals(e.key)) {
    377                 V oldValue = e.value;
    378                 e.value = value;
    379                 return oldValue;
    380             }
    381         }
    382 
    383         // No entry for key is present; create one
    384         modCount++;
    385         if (size++ > threshold) {
    386             rehash();  // Does nothing!!
    387             tab = doubleCapacity();
    388             index = hash & (tab.length - 1);
    389             first = tab[index];
    390         }
    391         tab[index] = new HashtableEntry<K, V>(key, value, hash, first);
    392         return null;
    393     }
    394 
    395     /**
    396      * This method is just like put, except that it doesn't do things that
    397      * are inappropriate or unnecessary for constructors and pseudo-constructors
    398      * (i.e., clone, readObject). In particular, this method does not check to
    399      * ensure that capacity is sufficient, and does not increment modCount.
    400      */
    401     private void constructorPut(K key, V value) {
    402         if (value == null) {
    403             throw new NullPointerException();
    404         }
    405         int hash = secondaryHash(key.hashCode());
    406         HashtableEntry<K, V>[] tab = table;
    407         int index = hash & (tab.length - 1);
    408         HashtableEntry<K, V> first = tab[index];
    409         for (HashtableEntry<K, V> e = first; e != null; e = e.next) {
    410             if (e.hash == hash && key.equals(e.key)) {
    411                 e.value = value;
    412                 return;
    413             }
    414         }
    415 
    416         // No entry for key is present; create one
    417         tab[index] = new HashtableEntry<K, V>(key, value, hash, first);
    418         size++;
    419     }
    420 
    421     /**
    422      * Copies every mapping to this {@code Hashtable} from the specified map.
    423      *
    424      * @param map
    425      *            the map to copy mappings from.
    426      */
    427     public synchronized void putAll(Map<? extends K, ? extends V> map) {
    428         ensureCapacity(map.size());
    429         for (Entry<? extends K, ? extends V> e : map.entrySet()) {
    430             put(e.getKey(), e.getValue());
    431         }
    432     }
    433 
    434     /**
    435      * Ensures that the hash table has sufficient capacity to store the
    436      * specified number of mappings, with room to grow. If not, it increases the
    437      * capacity as appropriate. Like doubleCapacity, this method moves existing
    438      * entries to new buckets as appropriate. Unlike doubleCapacity, this method
    439      * can grow the table by factors of 2^n for n > 1. Hopefully, a single call
    440      * to this method will be faster than multiple calls to doubleCapacity.
    441      *
    442      *  <p>This method is called only by putAll.
    443      */
    444     private void ensureCapacity(int numMappings) {
    445         int newCapacity = roundUpToPowerOfTwo(capacityForInitSize(numMappings));
    446         HashtableEntry<K, V>[] oldTable = table;
    447         int oldCapacity = oldTable.length;
    448         if (newCapacity <= oldCapacity) {
    449             return;
    450         }
    451 
    452         rehash();  // Does nothing!!
    453 
    454         if (newCapacity == oldCapacity << 1) {
    455             doubleCapacity();
    456             return;
    457         }
    458 
    459         // We're growing by at least 4x, rehash in the obvious way
    460         HashtableEntry<K, V>[] newTable = makeTable(newCapacity);
    461         if (size != 0) {
    462             int newMask = newCapacity - 1;
    463             for (int i = 0; i < oldCapacity; i++) {
    464                 for (HashtableEntry<K, V> e = oldTable[i]; e != null;) {
    465                     HashtableEntry<K, V> oldNext = e.next;
    466                     int newIndex = e.hash & newMask;
    467                     HashtableEntry<K, V> newNext = newTable[newIndex];
    468                     newTable[newIndex] = e;
    469                     e.next = newNext;
    470                     e = oldNext;
    471                 }
    472             }
    473         }
    474     }
    475 
    476     /**
    477      * Increases the capacity of this {@code Hashtable}. This method is called
    478      * when the size of this {@code Hashtable} exceeds the load factor.
    479      */
    480     protected void rehash() {
    481         /*
    482          * This method has no testable semantics, other than that it gets
    483          * called from time to time.
    484          */
    485     }
    486 
    487     /**
    488      * Allocate a table of the given capacity and set the threshold accordingly.
    489      * @param newCapacity must be a power of two
    490      */
    491     private HashtableEntry<K, V>[] makeTable(int newCapacity) {
    492         @SuppressWarnings("unchecked") HashtableEntry<K, V>[] newTable
    493                 = (HashtableEntry<K, V>[]) new HashtableEntry[newCapacity];
    494         table = newTable;
    495         threshold = (newCapacity >> 1) + (newCapacity >> 2); // 3/4 capacity
    496         return newTable;
    497     }
    498 
    499     /**
    500      * Doubles the capacity of the hash table. Existing entries are placed in
    501      * the correct bucket on the enlarged table. If the current capacity is,
    502      * MAXIMUM_CAPACITY, this method is a no-op. Returns the table, which
    503      * will be new unless we were already at MAXIMUM_CAPACITY.
    504      */
    505     private HashtableEntry<K, V>[] doubleCapacity() {
    506         HashtableEntry<K, V>[] oldTable = table;
    507         int oldCapacity = oldTable.length;
    508         if (oldCapacity == MAXIMUM_CAPACITY) {
    509             return oldTable;
    510         }
    511         int newCapacity = oldCapacity << 1;
    512         HashtableEntry<K, V>[] newTable = makeTable(newCapacity);
    513         if (size == 0) {
    514             return newTable;
    515         }
    516 
    517         for (int j = 0; j < oldCapacity; j++) {
    518             /*
    519              * Rehash the bucket using the minimum number of field writes.
    520              * This is the most subtle and delicate code in the class.
    521              */
    522             HashtableEntry<K, V> e = oldTable[j];
    523             if (e == null) {
    524                 continue;
    525             }
    526             int highBit = e.hash & oldCapacity;
    527             HashtableEntry<K, V> broken = null;
    528             newTable[j | highBit] = e;
    529             for (HashtableEntry<K,V> n = e.next; n != null; e = n, n = n.next) {
    530                 int nextHighBit = n.hash & oldCapacity;
    531                 if (nextHighBit != highBit) {
    532                     if (broken == null)
    533                         newTable[j | nextHighBit] = n;
    534                     else
    535                         broken.next = n;
    536                     broken = e;
    537                     highBit = nextHighBit;
    538                 }
    539             }
    540             if (broken != null)
    541                 broken.next = null;
    542         }
    543         return newTable;
    544     }
    545 
    546     /**
    547      * Removes the key/value pair with the specified key from this
    548      * {@code Hashtable}.
    549      *
    550      * @param key
    551      *            the key to remove.
    552      * @return the value associated with the specified key, or {@code null} if
    553      *         the specified key did not exist.
    554      * @see #get
    555      * @see #put
    556      */
    557     public synchronized V remove(Object key) {
    558         int hash = secondaryHash(key.hashCode());
    559         HashtableEntry<K, V>[] tab = table;
    560         int index = hash & (tab.length - 1);
    561         for (HashtableEntry<K, V> e = tab[index], prev = null;
    562                 e != null; prev = e, e = e.next) {
    563             if (e.hash == hash && key.equals(e.key)) {
    564                 if (prev == null) {
    565                     tab[index] = e.next;
    566                 } else {
    567                     prev.next = e.next;
    568                 }
    569                 modCount++;
    570                 size--;
    571                 return e.value;
    572             }
    573         }
    574         return null;
    575     }
    576 
    577     /**
    578      * Removes all key/value pairs from this {@code Hashtable}, leaving the
    579      * size zero and the capacity unchanged.
    580      *
    581      * @see #isEmpty
    582      * @see #size
    583      */
    584     public synchronized void clear() {
    585         if (size != 0) {
    586             Arrays.fill(table, null);
    587             modCount++;
    588             size = 0;
    589         }
    590     }
    591 
    592     /**
    593      * Returns a set of the keys contained in this {@code Hashtable}. The set
    594      * is backed by this {@code Hashtable} so changes to one are reflected by
    595      * the other. The set does not support adding.
    596      *
    597      * @return a set of the keys.
    598      */
    599     public synchronized Set<K> keySet() {
    600         Set<K> ks = keySet;
    601         return (ks != null) ? ks : (keySet = new KeySet());
    602     }
    603 
    604     /**
    605      * Returns a collection of the values contained in this {@code Hashtable}.
    606      * The collection is backed by this {@code Hashtable} so changes to one are
    607      * reflected by the other. The collection does not support adding.
    608      *
    609      * @return a collection of the values.
    610      */
    611     public synchronized Collection<V> values() {
    612         Collection<V> vs = values;
    613         return (vs != null) ? vs : (values = new Values());
    614     }
    615 
    616     /**
    617      * Returns a set of the mappings contained in this {@code Hashtable}. Each
    618      * element in the set is a {@link Map.Entry}. The set is backed by this
    619      * {@code Hashtable} so changes to one are reflected by the other. The set
    620      * does not support adding.
    621      *
    622      * @return a set of the mappings.
    623      */
    624     public synchronized Set<Entry<K, V>> entrySet() {
    625         Set<Entry<K, V>> es = entrySet;
    626         return (es != null) ? es : (entrySet = new EntrySet());
    627     }
    628 
    629 
    630     /**
    631      * Returns an enumeration on the keys of this {@code Hashtable} instance.
    632      * The results of the enumeration may be affected if the contents of this
    633      * {@code Hashtable} are modified.
    634      *
    635      * @return an enumeration of the keys of this {@code Hashtable}.
    636      * @see #elements
    637      * @see #size
    638      * @see Enumeration
    639      */
    640     public synchronized Enumeration<K> keys() {
    641         return new KeyEnumeration();
    642     }
    643 
    644     /**
    645      * Returns an enumeration on the values of this {@code Hashtable}. The
    646      * results of the Enumeration may be affected if the contents of this
    647      * {@code Hashtable} are modified.
    648      *
    649      * @return an enumeration of the values of this {@code Hashtable}.
    650      * @see #keys
    651      * @see #size
    652      * @see Enumeration
    653      */
    654     public synchronized Enumeration<V> elements() {
    655         return new ValueEnumeration();
    656     }
    657 
    658     /**
    659      * Note: technically the methods of this class should synchronize the
    660      * backing map.  However, this would require them to have a reference
    661      * to it, which would cause considerable bloat.  Moreover, the RI
    662      * behaves the same way.
    663      */
    664     private static class HashtableEntry<K, V> implements Entry<K, V> {
    665         final K key;
    666         V value;
    667         final int hash;
    668         HashtableEntry<K, V> next;
    669 
    670         HashtableEntry(K key, V value, int hash, HashtableEntry<K, V> next) {
    671             this.key = key;
    672             this.value = value;
    673             this.hash = hash;
    674             this.next = next;
    675         }
    676 
    677         public final K getKey() {
    678             return key;
    679         }
    680 
    681         public final V getValue() {
    682             return value;
    683         }
    684 
    685         public final V setValue(V value) {
    686             if (value == null) {
    687                 throw new NullPointerException();
    688             }
    689             V oldValue = this.value;
    690             this.value = value;
    691             return oldValue;
    692         }
    693 
    694         @Override public final boolean equals(Object o) {
    695             if (!(o instanceof Entry)) {
    696                 return false;
    697             }
    698             Entry<?, ?> e = (Entry<?, ?>) o;
    699             return key.equals(e.getKey()) && value.equals(e.getValue());
    700         }
    701 
    702         @Override public final int hashCode() {
    703             return key.hashCode() ^ value.hashCode();
    704         }
    705 
    706         @Override public final String toString() {
    707             return key + "=" + value;
    708         }
    709     }
    710 
    711     private abstract class HashIterator {
    712         int nextIndex;
    713         HashtableEntry<K, V> nextEntry;
    714         HashtableEntry<K, V> lastEntryReturned;
    715         int expectedModCount = modCount;
    716 
    717         HashIterator() {
    718             HashtableEntry<K, V>[] tab = table;
    719             HashtableEntry<K, V> next = null;
    720             while (next == null && nextIndex < tab.length) {
    721                 next = tab[nextIndex++];
    722             }
    723             nextEntry = next;
    724         }
    725 
    726         public boolean hasNext() {
    727             return nextEntry != null;
    728         }
    729 
    730         HashtableEntry<K, V> nextEntry() {
    731             if (modCount != expectedModCount)
    732                 throw new ConcurrentModificationException();
    733             if (nextEntry == null)
    734                 throw new NoSuchElementException();
    735 
    736             HashtableEntry<K, V> entryToReturn = nextEntry;
    737             HashtableEntry<K, V>[] tab = table;
    738             HashtableEntry<K, V> next = entryToReturn.next;
    739             while (next == null && nextIndex < tab.length) {
    740                 next = tab[nextIndex++];
    741             }
    742             nextEntry = next;
    743             return lastEntryReturned = entryToReturn;
    744         }
    745 
    746         HashtableEntry<K, V> nextEntryNotFailFast() {
    747             if (nextEntry == null)
    748                 throw new NoSuchElementException();
    749 
    750             HashtableEntry<K, V> entryToReturn = nextEntry;
    751             HashtableEntry<K, V>[] tab = table;
    752             HashtableEntry<K, V> next = entryToReturn.next;
    753             while (next == null && nextIndex < tab.length) {
    754                 next = tab[nextIndex++];
    755             }
    756             nextEntry = next;
    757             return lastEntryReturned = entryToReturn;
    758         }
    759 
    760         public void remove() {
    761             if (lastEntryReturned == null)
    762                 throw new IllegalStateException();
    763             if (modCount != expectedModCount)
    764                 throw new ConcurrentModificationException();
    765             Hashtable.this.remove(lastEntryReturned.key);
    766             lastEntryReturned = null;
    767             expectedModCount = modCount;
    768         }
    769     }
    770 
    771     private final class KeyIterator extends HashIterator
    772             implements Iterator<K> {
    773         public K next() { return nextEntry().key; }
    774     }
    775 
    776     private final class ValueIterator extends HashIterator
    777             implements Iterator<V> {
    778         public V next() { return nextEntry().value; }
    779     }
    780 
    781     private final class EntryIterator extends HashIterator
    782             implements Iterator<Entry<K, V>> {
    783         public Entry<K, V> next() { return nextEntry(); }
    784     }
    785 
    786     private final class KeyEnumeration extends HashIterator
    787             implements Enumeration<K> {
    788         public boolean hasMoreElements() { return hasNext(); }
    789         public K nextElement() { return nextEntryNotFailFast().key; }
    790     }
    791 
    792     private final class ValueEnumeration extends HashIterator
    793             implements Enumeration<V> {
    794         public boolean hasMoreElements() { return hasNext(); }
    795         public V nextElement() { return nextEntryNotFailFast().value; }
    796     }
    797 
    798     /**
    799      * Returns true if this map contains the specified mapping.
    800      */
    801     private synchronized boolean containsMapping(Object key, Object value) {
    802         int hash = secondaryHash(key.hashCode());
    803         HashtableEntry<K, V>[] tab = table;
    804         int index = hash & (tab.length - 1);
    805         for (HashtableEntry<K, V> e = tab[index]; e != null; e = e.next) {
    806             if (e.hash == hash && e.key.equals(key)) {
    807                 return e.value.equals(value);
    808             }
    809         }
    810         return false; // No entry for key
    811     }
    812 
    813     /**
    814      * Removes the mapping from key to value and returns true if this mapping
    815      * exists; otherwise, returns does nothing and returns false.
    816      */
    817     private synchronized boolean removeMapping(Object key, Object value) {
    818         int hash = secondaryHash(key.hashCode());
    819         HashtableEntry<K, V>[] tab = table;
    820         int index = hash & (tab.length - 1);
    821         for (HashtableEntry<K, V> e = tab[index], prev = null;
    822                 e != null; prev = e, e = e.next) {
    823             if (e.hash == hash && e.key.equals(key)) {
    824                 if (!e.value.equals(value)) {
    825                     return false;  // Map has wrong value for key
    826                 }
    827                 if (prev == null) {
    828                     tab[index] = e.next;
    829                 } else {
    830                     prev.next = e.next;
    831                 }
    832                 modCount++;
    833                 size--;
    834                 return true;
    835             }
    836         }
    837         return false; // No entry for key
    838     }
    839 
    840     /**
    841      * Compares this {@code Hashtable} with the specified object and indicates
    842      * if they are equal. In order to be equal, {@code object} must be an
    843      * instance of Map and contain the same key/value pairs.
    844      *
    845      * @param object
    846      *            the object to compare with this object.
    847      * @return {@code true} if the specified object is equal to this Map,
    848      *         {@code false} otherwise.
    849      * @see #hashCode
    850      */
    851     @Override public synchronized boolean equals(Object object) {
    852         return (object instanceof Map) &&
    853                 entrySet().equals(((Map<?, ?>)object).entrySet());
    854     }
    855 
    856     @Override public synchronized int hashCode() {
    857         int result = 0;
    858         for (Entry<K, V> e : entrySet()) {
    859             K key = e.getKey();
    860             V value = e.getValue();
    861             if (key == this || value == this) {
    862                 continue;
    863             }
    864             result += (key != null ? key.hashCode() : 0)
    865                     ^ (value != null ? value.hashCode() : 0);
    866         }
    867         return result;
    868     }
    869 
    870     /**
    871      * A rough estimate of the number of characters per entry, for use
    872      * when creating a string buffer in the toString method.
    873      */
    874     private static final int CHARS_PER_ENTRY = 15;
    875 
    876     /**
    877      * Returns the string representation of this {@code Hashtable}.
    878      *
    879      * @return the string representation of this {@code Hashtable}.
    880      */
    881     @Override public synchronized String toString() {
    882         StringBuilder result = new StringBuilder(CHARS_PER_ENTRY * size);
    883         result.append('{');
    884         Iterator<Entry<K, V>> i = entrySet().iterator();
    885         boolean hasMore = i.hasNext();
    886         while (hasMore) {
    887             Entry<K, V> entry = i.next();
    888 
    889             K key = entry.getKey();
    890             result.append(key == this ? "(this Map)" : key.toString());
    891 
    892             result.append('=');
    893 
    894             V value = entry.getValue();
    895             result.append(value == this ? "(this Map)" : value.toString());
    896 
    897             if (hasMore = i.hasNext()) {
    898                 result.append(", ");
    899             }
    900         }
    901 
    902         result.append('}');
    903         return result.toString();
    904     }
    905 
    906     private final class KeySet extends AbstractSet<K> {
    907         public Iterator<K> iterator() {
    908             return new KeyIterator();
    909         }
    910         public int size() {
    911             return Hashtable.this.size();
    912         }
    913         public boolean contains(Object o) {
    914             return containsKey(o);
    915         }
    916         public boolean remove(Object o) {
    917             synchronized (Hashtable.this) {
    918                 int oldSize = size;
    919                 Hashtable.this.remove(o);
    920                 return size != oldSize;
    921             }
    922         }
    923         public void clear() {
    924             Hashtable.this.clear();
    925         }
    926         public boolean removeAll(Collection<?> collection) {
    927             synchronized (Hashtable.this) {
    928                 return super.removeAll(collection);
    929             }
    930         }
    931         public boolean retainAll(Collection<?> collection) {
    932             synchronized (Hashtable.this) {
    933                 return super.retainAll(collection);
    934             }
    935         }
    936         public boolean containsAll(Collection<?> collection) {
    937             synchronized (Hashtable.this) {
    938                 return super.containsAll(collection);
    939             }
    940         }
    941         public boolean equals(Object object) {
    942             synchronized (Hashtable.this) {
    943                 return super.equals(object);
    944             }
    945         }
    946         public int hashCode() {
    947             synchronized (Hashtable.this) {
    948                 return super.hashCode();
    949             }
    950         }
    951         public String toString() {
    952             synchronized (Hashtable.this) {
    953                 return super.toString();
    954             }
    955         }
    956         public Object[] toArray() {
    957             synchronized (Hashtable.this) {
    958                 return super.toArray();
    959             }
    960         }
    961         public <T> T[] toArray(T[] a) {
    962             synchronized (Hashtable.this) {
    963                 return super.toArray(a);
    964             }
    965         }
    966     }
    967 
    968     private final class Values extends AbstractCollection<V> {
    969         public Iterator<V> iterator() {
    970             return new ValueIterator();
    971         }
    972         public int size() {
    973             return Hashtable.this.size();
    974         }
    975         public boolean contains(Object o) {
    976             return containsValue(o);
    977         }
    978         public void clear() {
    979             Hashtable.this.clear();
    980         }
    981         public boolean containsAll(Collection<?> collection) {
    982             synchronized (Hashtable.this) {
    983                 return super.containsAll(collection);
    984             }
    985         }
    986         public String toString() {
    987             synchronized (Hashtable.this) {
    988                 return super.toString();
    989             }
    990         }
    991         public Object[] toArray() {
    992             synchronized (Hashtable.this) {
    993                 return super.toArray();
    994             }
    995         }
    996         public <T> T[] toArray(T[] a) {
    997             synchronized (Hashtable.this) {
    998                 return super.toArray(a);
    999             }
   1000         }
   1001     }
   1002 
   1003     private final class EntrySet extends AbstractSet<Entry<K, V>> {
   1004         public Iterator<Entry<K, V>> iterator() {
   1005             return new EntryIterator();
   1006         }
   1007         public boolean contains(Object o) {
   1008             if (!(o instanceof Entry))
   1009                 return false;
   1010             Entry<?, ?> e = (Entry<?, ?>) o;
   1011             return containsMapping(e.getKey(), e.getValue());
   1012         }
   1013         public boolean remove(Object o) {
   1014             if (!(o instanceof Entry))
   1015                 return false;
   1016             Entry<?, ?> e = (Entry<?, ?>)o;
   1017             return removeMapping(e.getKey(), e.getValue());
   1018         }
   1019         public int size() {
   1020             return Hashtable.this.size();
   1021         }
   1022         public void clear() {
   1023             Hashtable.this.clear();
   1024         }
   1025         public boolean removeAll(Collection<?> collection) {
   1026             synchronized (Hashtable.this) {
   1027                 return super.removeAll(collection);
   1028             }
   1029         }
   1030         public boolean retainAll(Collection<?> collection) {
   1031             synchronized (Hashtable.this) {
   1032                 return super.retainAll(collection);
   1033             }
   1034         }
   1035         public boolean containsAll(Collection<?> collection) {
   1036             synchronized (Hashtable.this) {
   1037                 return super.containsAll(collection);
   1038             }
   1039         }
   1040         public boolean equals(Object object) {
   1041             synchronized (Hashtable.this) {
   1042                 return super.equals(object);
   1043             }
   1044         }
   1045         public int hashCode() {
   1046             return Hashtable.this.hashCode();
   1047         }
   1048         public String toString() {
   1049             synchronized (Hashtable.this) {
   1050                 return super.toString();
   1051             }
   1052         }
   1053         public Object[] toArray() {
   1054             synchronized (Hashtable.this) {
   1055                 return super.toArray();
   1056             }
   1057         }
   1058         public <T> T[] toArray(T[] a) {
   1059             synchronized (Hashtable.this) {
   1060                 return super.toArray(a);
   1061             }
   1062         }
   1063     }
   1064 
   1065     /**
   1066      * Applies a supplemental hash function to a given hashCode, which defends
   1067      * against poor quality hash functions. This is critical because Hashtable
   1068      * uses power-of-two length hash tables, that otherwise encounter collisions
   1069      * for hashCodes that do not differ in lower or upper bits.
   1070      */
   1071     private static int secondaryHash(int h) {
   1072         // Doug Lea's supplemental hash function
   1073         h ^= (h >>> 20) ^ (h >>> 12);
   1074         return h ^ (h >>> 7) ^ (h >>> 4);
   1075     }
   1076 
   1077     /**
   1078      * Returns the smallest power of two >= its argument, with several caveats:
   1079      * If the argument is negative but not Integer.MIN_VALUE, the method returns
   1080      * zero. If the argument is > 2^30 or equal to Integer.MIN_VALUE, the method
   1081      * returns Integer.MIN_VALUE. If the argument is zero, the method returns
   1082      * zero.
   1083      */
   1084     private static int roundUpToPowerOfTwo(int i) {
   1085         i--; // If input is a power of two, shift its high-order bit right
   1086 
   1087         // "Smear" the high-order bit all the way to the right
   1088         i |= i >>>  1;
   1089         i |= i >>>  2;
   1090         i |= i >>>  4;
   1091         i |= i >>>  8;
   1092         i |= i >>> 16;
   1093 
   1094         return i + 1;
   1095     }
   1096 
   1097     private static final long serialVersionUID = 1421746759512286392L;
   1098 
   1099     /**
   1100      * Serializable fields.
   1101      *
   1102      * @serialField loadFactor float
   1103      *              load factor for this Hashtable
   1104      */
   1105     private static final ObjectStreamField[] serialPersistentFields = {
   1106         new ObjectStreamField("threshold", Integer.TYPE),
   1107         new ObjectStreamField("loadFactor", Float.TYPE)
   1108     };
   1109 
   1110     private synchronized void writeObject(ObjectOutputStream stream)
   1111             throws IOException {
   1112         // Emulate loadFactor field for other implementations to read
   1113         ObjectOutputStream.PutField fields = stream.putFields();
   1114         fields.put("threshold",  (int) (DEFAULT_LOAD_FACTOR * table.length));
   1115         fields.put("loadFactor", DEFAULT_LOAD_FACTOR);
   1116         stream.writeFields();
   1117 
   1118         stream.writeInt(table.length); // Capacity
   1119         stream.writeInt(size);
   1120         for (Entry<K, V> e : entrySet()) {
   1121             stream.writeObject(e.getKey());
   1122             stream.writeObject(e.getValue());
   1123         }
   1124     }
   1125 
   1126     private void readObject(ObjectInputStream stream) throws IOException,
   1127             ClassNotFoundException {
   1128         stream.defaultReadObject();
   1129         int capacity = stream.readInt();
   1130         if (capacity < 0) {
   1131             throw new InvalidObjectException("Capacity: " + capacity);
   1132         }
   1133         if (capacity < MINIMUM_CAPACITY) {
   1134             capacity = MINIMUM_CAPACITY;
   1135         } else if (capacity > MAXIMUM_CAPACITY) {
   1136             capacity = MAXIMUM_CAPACITY;
   1137         } else {
   1138             capacity = roundUpToPowerOfTwo(capacity);
   1139         }
   1140         makeTable(capacity);
   1141 
   1142         int size = stream.readInt();
   1143         if (size < 0) {
   1144             throw new InvalidObjectException("Size: " + size);
   1145         }
   1146 
   1147         for (int i = 0; i < size; i++) {
   1148             @SuppressWarnings("unchecked") K key = (K) stream.readObject();
   1149             @SuppressWarnings("unchecked") V val = (V) stream.readObject();
   1150             constructorPut(key, val);
   1151         }
   1152     }
   1153 }
   1154