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