從源碼理解Hashtable.java

package java.util;

import java.io.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.BiFunction;

/**
 * Hashtable實現了哈希表,把關鍵字映射到值,不允許空值null
 * 作爲關鍵字的對象必須實現hashCode和equals方法,以便從hashtable中存取對象
 * 一個Hashtable對象有兩個參數影響其性能:初始容量和裝載因子。容量是哈希表中槽bucket的數目,初始容量只是創建時候的容量
 * 哈希表對於哈希衝突是開放式的,一個槽中可能會存儲多個Entry,遍歷的時候只能順序遍歷。
 * 裝載因子用來衡量哈希表達到多滿的程度的時候需要重新哈希,具體什麼時候是否需要調用rehash方法還要看具體實現
 * 通常默認的裝載因子0.75提供了一個很好的時空取捨
 * 初始容量控制了空間浪費與相當耗費時間的rehash操作的必要性之間的取捨。較大的初始容量可以保證不必rehash,但初始容量過大又容易浪費空間。
 * 如果有很多Entry需要放進Hashtable,那就創建一個初始容量比較大的哈希表,比自動增長rehash的插入更加高效
 * hashtable的使用例子:
 *   Hashtable<String, Integer> numbers
 *     = new Hashtable<String, Integer>();
 *   numbers.put("one", 1);
 *   numbers.put("two", 2);
 *   numbers.put("three", 3);}
 * 取數據的操作:
 *   Integer n = numbers.get("two");
 *   if (n != null) {
 *     System.out.println("two = " + n);
 *   }}
 * 通過iterator方法返回的迭代器都是fail-fast的:如果迭代器創建之後hashtable發生除了通過迭代器自己的remove函數之外的結構改變,都會拋出ConcurrentModificationException異常
 * Hashtable的keys和elements方法返回的枚舉集合enumerator不是fail-fast的
 */
/**
 * Hashtable繼承於Dictionary,實現了Map、Cloneable、java.io.Serializable接口
 * Hashtable的函數都是同步的,這意味着它是線程安全的。它的key、value都不可以爲null。此外,Hashtable中的映射不是有序的。
 * 涉及到結構改變的函數操作都使用synchronized修飾
 */
public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable {

    /**
     * 哈希表中存放數據的地方.
     */
    private transient Entry<?,?>[] table;

    /**
     * 哈希表中所有Entry的數目
     */
    private transient int count;

    /**
     * 重新哈希的閾值(threshold = (int)capacity * loadFactor)
     */
    private int threshold;

    /**
     * hashtable的裝載因子
     */
    private float loadFactor;

    /**
     * Hashtable的結構修改次數。結構修改指的是改變Entry數目或是修改內部結構(如rehash)
     * 這個字段用來使Hashtable的集合視圖fail-fast的。
     */
    private transient int modCount = 0;

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = 1421746759512286392L;

    /**
     * 構造函數1:構造一個指定容量和裝載因子的空哈希表
     * @param      initialCapacity   the initial capacity of the hashtable.
     * @param      loadFactor        the load factor of the hashtable.
     * @exception  IllegalArgumentException  if the initial capacity is less
     *             than zero, or if the load factor is nonpositive.
     */
    public Hashtable(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal Load: "+loadFactor);

        if (initialCapacity==0)
            initialCapacity = 1;
        this.loadFactor = loadFactor;
        table = new Entry<?,?>[initialCapacity];
        threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
    }

    /**
     * 構造函數2:構造一個指定容量的空哈希表,默認裝載因子0.75
     * @param     initialCapacity   the initial capacity of the hashtable.
     * @exception IllegalArgumentException if the initial capacity is less
     *              than zero.
     */
    public Hashtable(int initialCapacity) {
        this(initialCapacity, 0.75f);
    }

    /**
     * 構造函數3:構造一個空哈希表,默認容量11,默認裝載因子0.75
     */
    public Hashtable() {
        this(11, 0.75f);
    }

    /**
     * 構造函數4:構造一個包含子Map的構造函數,容量爲足夠容納指定Map中元素的2的次冪,默認裝載因子0.75
     * @param t the map whose mappings are to be placed in this map.
     * @throws NullPointerException if the specified map is null.
     */
    public Hashtable(Map<? extends K, ? extends V> t) {
        this(Math.max(2*t.size(), 11), 0.75f);
        putAll(t);
    }

    /**
     * 返回Hashtable中鍵值對的數目,方法由synchronized修飾,支持同步調用
     * @return  the number of keys in this hashtable.
     */
    public synchronized int size() {
        return count;
    }

    /**
     * 測試Hashtable是否爲空,方法由synchronized修飾,支持同步調用
     * @return  <code>true</code> if this hashtable maps no keys to values;
     *          <code>false</code> otherwise.
     */
    public synchronized boolean isEmpty() {
        return count == 0;
    }

    /**
     * 返回Hashtable中所有關鍵字的一個枚舉集合,方法由synchronized修飾,支持同步調用
     * @return  an enumeration of the keys in this hashtable.
     * @see     Enumeration
     * @see     #elements()
     * @see     #keySet()
     * @see     Map
     */
    public synchronized Enumeration<K> keys() {
        return this.<K>getEnumeration(KEYS);
    }

    /**
     * 返回Hashtable中所有值對象的枚舉集合,使用返回對象的getEnumeration方法順序獲取元素
     * @return  an enumeration of the values in this hashtable.
     */
    public synchronized Enumeration<V> elements() {
        return this.<V>getEnumeration(VALUES);
    }

    /**
     * 測試Hashtable中是否有關鍵字映射到指定值上。contains(value)比containsKey(key)方法耗時多一些。
     * 這個方法與Map接口containsValue方法功能相同
     * @param      value   a value to search for
     * @return     <code>true</code> if and only if some key maps to the
     *             <code>value</code> argument in this hashtable as
     *             determined by the <tt>equals</tt> method;
     *             <code>false</code> otherwise.
     * @exception  NullPointerException  if the value is <code>null</code>
     */
    public synchronized boolean contains(Object value) {
    		//Hashtable中“鍵值對”的value不能使null,否則拋出異常NullPointerException
        if (value == null) {
            throw new NullPointerException();
        }
        	//從後向前遍歷table數組中的元素(Entry)
        	//對於每個Entry(單向鏈表),逐個遍歷,判斷結點的值是否等於value
        Entry<?,?> tab[] = table;
        for (int i = tab.length ; i-- > 0 ;) {
            for (Entry<?,?> e = tab[i] ; e != null ; e = e.next) {
                if (e.value.equals(value)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 與contains功能一樣,本質就是調用了contains函數
     * @param value value whose presence in this hashtable is to be tested
     * @return <tt>true</tt> if this map maps one or more keys to the
     *         specified value
     * @throws NullPointerException  if the value is <code>null</code>
     * @since 1.2
     */
    public boolean containsValue(Object value) {
        return contains(value);
    }

    /**
     * 測試指定Key是否存在
     * @param   key   possible key
     * @return  <code>true</code> if and only if the specified object
     *          is a key in this hashtable, as determined by the
     *          <tt>equals</tt> method; <code>false</code> otherwise.
     * @throws  NullPointerException  if the key is <code>null</code>
     */
    public synchronized boolean containsKey(Object key) {
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        	//關鍵字Key映射的哈希槽下標
        int index = (hash & 0x7FFFFFFF) % tab.length;
        	//遍歷鏈表找到與指定Key相等(equals)的元素
        for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 返回指定關鍵字Key的value值,不存在則返回null
     * @param key the key whose associated value is to be returned
     * @return the value to which the specified key is mapped, or
     *         {@code null} if this map contains no mapping for the key
     * @throws NullPointerException if the specified key is null
     * @see     #put(Object, Object)
     */
    @SuppressWarnings("unchecked")
    public synchronized V get(Object key) {
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        	//計算指定關鍵字映射的哈希槽
        int index = (hash & 0x7FFFFFFF) % tab.length;
        	//遍歷單向鏈表
        for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return (V)e.value;
            }
        }
        return null;
    }

    /**
     * 分配數組最大容量,一些虛擬機會保存數組的頭字,試圖分配更大的數組會導致OOM(OutOfMemoryError):請求的數組容量超出VM限制
     */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * 容量增長時需要內部重新組織Hashtable,以更有效率的訪問
     * 當Hashtable中關鍵字數目超出容量與裝載因子之積時,自動調用該方法
     */
    @SuppressWarnings("unchecked")
    protected void rehash() {
        int oldCapacity = table.length;	//舊容量
        Entry<?,?>[] oldMap = table;	//舊Entry數組

        // 溢出檢測(超出MAX_ARRAY_SIZE)
        int newCapacity = (oldCapacity << 1) + 1;
        if (newCapacity - MAX_ARRAY_SIZE > 0) {
            if (oldCapacity == MAX_ARRAY_SIZE)
                // Keep running with MAX_ARRAY_SIZE buckets
                return;
            newCapacity = MAX_ARRAY_SIZE;
        }
        	//申請新Entry數組
        Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];
        	//修改modCount
        modCount++;
        	//修改新閾值(新閾值也不能超過MAX_ARRAY_SIZE)
        threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
        table = newMap;
        	//從後向前遍歷舊錶每一個槽中的鏈表的每一個Entry元素,將其重新哈希到新表中
        for (int i = oldCapacity ; i-- > 0 ;) {
            for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {
                Entry<K,V> e = old;
                old = old.next;

                int index = (e.hash & 0x7FFFFFFF) % newCapacity;
                	//將e插入Index槽中當前鏈表的開頭
                e.next = (Entry<K,V>)newMap[index];
                newMap[index] = e;
            }
        }
    }
    	//添加新的Entry元素
    private void addEntry(int hash, K key, V value, int index) {
        modCount++;

        Entry<?,?> tab[] = table;
        	//超過閾值,需要重新哈希
        if (count >= threshold) {
            // Rehash the table if the threshold is exceeded
            rehash();

            tab = table;
            hash = key.hashCode();
            index = (hash & 0x7FFFFFFF) % tab.length;
        }
        // 創建新的Entry,並插入Index槽中鏈表的頭部
        @SuppressWarnings("unchecked")
        Entry<K,V> e = (Entry<K,V>) tab[index];
        tab[index] = new Entry<>(hash, key, value, e);
        count++;
    }

    /**
     * 將指定的Key映射到指定的value。Key和value都不能爲空null
     * @param      key     the hashtable key
     * @param      value   the value
     * @return     the previous value of the specified key in this hashtable,
     *             or <code>null</code> if it did not have one
     * @exception  NullPointerException  if the key or value is
     *               <code>null</code>
     */
    public synchronized V put(K key, V value) {
        // 確保value不爲空null
        if (value == null) {
            throw new NullPointerException();
        }
        // 確保Key在Hashtable中不存在,若存在,更新value,並返回舊值
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> entry = (Entry<K,V>)tab[index];
        for(; entry != null ; entry = entry.next) {
            if ((entry.hash == hash) && entry.key.equals(key)) {
                V old = entry.value;
                entry.value = value;
                return old;
            }
        }
        	//不存在,添加元素
        addEntry(hash, key, value, index);
        return null;
    }

    /**
     * 刪除關鍵字Key相關的Entry,如果不存在Key,就什麼都不做(只是遍歷一趟鏈表。。)
     * @param   key   the key that needs to be removed
     * @return  the value to which the key had been mapped in this hashtable,
     *          or <code>null</code> if the key did not have a mapping
     * @throws  NullPointerException  if the key is <code>null</code>
     */
    public synchronized V remove(Object key) {
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        	//獲取下標Index
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> e = (Entry<K,V>)tab[index];
        for(Entry<K,V> prev = null ; e != null ; prev = e, e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                modCount++;
                	//刪除e
                if (prev != null) {
                    prev.next = e.next;
                } else {
                    tab[index] = e.next;
                }
                count--;
                V oldValue = e.value;
                e.value = null;
                	//返回刪除元素的value值
                return oldValue;
            }
        }
        return null;
    }

    /**
     * 將指定Map中的所有映射都拷貝到Hashtable中,已經存在的Key對應的value值會被更新
     * @param t mappings to be stored in this map
     * @throws NullPointerException if the specified map is null
     */
    public synchronized void putAll(Map<? extends K, ? extends V> t) {
        for (Map.Entry<? extends K, ? extends V> e : t.entrySet())
            put(e.getKey(), e.getValue());
    }

    /**
     * 清空Hashtable,將Hashtable的table數組的值全部設爲null
     */
    public synchronized void clear() {
        Entry<?,?> tab[] = table;
        modCount++;
        for (int index = tab.length; --index >= 0; )
            tab[index] = null;
        count = 0;
    }

    /**
     * 創建一個Hashtable的淺拷貝。Hashtable自身的結構都被拷貝了(拷貝數組,拷貝鏈表),但是其中的關鍵字和值不拷貝(依然引用的同一份Key和value)。
     * @return  a clone of the hashtable
     */
    public synchronized Object clone() {
        try {
            Hashtable<?,?> t = (Hashtable<?,?>)super.clone();
            t.table = new Entry<?,?>[table.length];
            for (int i = table.length ; i-- > 0 ; ) {
            		//依次調用數組裏的鏈表的第一個元素的clone方法,後繼元素都自動複製了,因爲clone中會調用後繼元素的clone
                t.table[i] = (table[i] != null)
                    ? (Entry<?,?>) table[i].clone() : null;
            }
            t.keySet = null;
            t.entrySet = null;
            t.values = null;
            t.modCount = 0;
            return t;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }

    /**
     * 返回Hashtable對象的String表達方式,一系列以括號和逗號,空格分隔的Entry,如{key1=value1, key2=value2}
     * @return  a string representation of this hashtable
     */
    public synchronized String toString() {
        int max = size() - 1;
        	//Hashtable中元素爲空
        if (max == -1)
            return "{}";
        	//使用StringBuilder,提高字符串拼接效率
        StringBuilder sb = new StringBuilder();
        	//獲得Hashtable的Entry集合
        Iterator<Map.Entry<K,V>> it = entrySet().iterator();

        sb.append('{');
        for (int i = 0; ; i++) {
            Map.Entry<K,V> e = it.next();
            K key = e.getKey();
            V value = e.getValue();
            sb.append(key   == this ? "(this Map)" : key.toString());
            sb.append('=');
            sb.append(value == this ? "(this Map)" : value.toString());

            if (i == max)
                return sb.append('}').toString();
            sb.append(", ");
        }
    }

    	//獲得指定類型(keys,values,entries)的枚舉集合
    private <T> Enumeration<T> getEnumeration(int type) {
        if (count == 0) {
            return Collections.emptyEnumeration();
        } else {
        		//傳false,新建枚舉器
            return new Enumerator<>(type, false);
        }
    }
    	//獲得指定類型(keys,values,entries)的迭代器
    private <T> Iterator<T> getIterator(int type) {
        if (count == 0) {
            return Collections.emptyIterator();
        } else {
        		//傳true參數,新建迭代器類型實例
            return new Enumerator<>(type, true);
        }
    }

    // 視圖

    /**
     * 以下每個字段初始化後會包含一個首次請求後的指定視圖,視圖是無狀態的,所以不必創建多個
     */
    private transient volatile Set<K> keySet = null;
    private transient volatile Set<Map.Entry<K,V>> entrySet = null;
    private transient volatile Collection<V> values = null;

    /**
     * 返回Map的關鍵字視圖Set,Map中的任何修改都會反映在Set中,反過來也是如此。當一個迭代器正在遍歷時,如果Map的結構發生改變,迭代器行爲未定義,
     * 如果是使用迭代器的remove函數改變Map結構,不會發生異常
     * set<K>支持Iterator.remove,Set.remove,removeAll,retainAll和clear函數
     * 不支持add和addAll函數
     */
    public Set<K> keySet() {
        if (keySet == null)
        		//返回線程安全的KeySet
            keySet = Collections.synchronizedSet(new KeySet(), this);
        return keySet;
    }
    //KeySet類
    private class KeySet extends AbstractSet<K> {
        public Iterator<K> iterator() {
        		//返回關鍵字迭代器
            return getIterator(KEYS);
        }
        public int size() {
            return count;
        }
        public boolean contains(Object o) {
            return containsKey(o);
        }
        public boolean remove(Object o) {
            return Hashtable.this.remove(o) != null;
        }
        public void clear() {
            Hashtable.this.clear();
        }
    }

    /**
     * 返回Map中映射的集合Set,Map中的改變會反映在Set中,反之亦是如此。
     * 迭代器遍歷Set時,如果Map結構發生變化,迭代器行爲未定義,除了通過迭代器自身的remove操作和setValue操作
     * 該Set支持通過Iterator.remove,Set.remove, removeAll, retainAll和clear操作刪除元素
     * 不支持add和addAll操作
     */
    public Set<Map.Entry<K,V>> entrySet() {
        if (entrySet==null)
        		//返回線程安全的entrySet
            entrySet = Collections.synchronizedSet(new EntrySet(), this);
        return entrySet;
    }

    private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
        public Iterator<Map.Entry<K,V>> iterator() {
        		//返回Entry的迭代器
            return getIterator(ENTRIES);
        }

        public boolean add(Map.Entry<K,V> o) {
            return super.add(o);
        }

        public boolean contains(Object o) {
        		//確定類型
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
            Object key = entry.getKey();
            Entry<?,?>[] tab = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;

            for (Entry<?,?> e = tab[index]; e != null; e = e.next)
            		//找到指定Entry
                if (e.hash==hash && e.equals(entry))
                    return true;
            return false;
        }

        public boolean remove(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
            Object key = entry.getKey();
            Entry<?,?>[] tab = table;
            int hash = key.hashCode();
            	//確定下標
            int index = (hash & 0x7FFFFFFF) % tab.length;

            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
            for(Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
                if (e.hash==hash && e.equals(entry)) {
                    modCount++;
                    	//刪除找到的元素
                    if (prev != null)
                        prev.next = e.next;
                    else
                        tab[index] = e.next;

                    count--;
                    e.value = null;
                    return true;
                }
            }
            return false;
        }

        public int size() {
            return count;
        }

        public void clear() {
            Hashtable.this.clear();
        }
    }

    /**
     * 返回Map中所有值的集合視圖,Map中的任何修改都會反映在集合中,反之亦是如此。如果集合遍歷過程中,Map發生結構上的修改,迭代行爲未定義
     * 除了通過迭代器自身的remove函數,集合支持元素刪除,通過Iterator.remove,Collection.remove,removeAll,retainAll和clear等行爲操作,
     * 但不支持add和addAll操作
     */
    public Collection<V> values() {
        if (values==null)
        		//返回線程安全的值集合
            values = Collections.synchronizedCollection(new ValueCollection(),
                                                        this);
        return values;
    }

    private class ValueCollection extends AbstractCollection<V> {
        public Iterator<V> iterator() {
        		//返回Values迭代器
            return getIterator(VALUES);
        }
        public int size() {
            return count;
        }
        public boolean contains(Object o) {
            return containsValue(o);
        }
        public void clear() {
            Hashtable.this.clear();
        }
    }

    // 比較和哈希函數
    /**
     * 比較指定對象和當前Map,判斷是否相等
     * @param  o object to be compared for equality with this hashtable
     * @return true if the specified Object is equal to this Map
     */
    public synchronized boolean equals(Object o) {
    		//同一個元素,返回true
        if (o == this)
            return true;
        	//類型不同,直接否定
        if (!(o instanceof Map))
            return false;
        Map<?,?> t = (Map<?,?>) o;
        if (t.size() != size())
            return false;

        try {
        		//獲取Entry的迭代器
            Iterator<Map.Entry<K,V>> i = entrySet().iterator();
            	//判斷Map中的每一個元素Entry的鍵值對是不是都在t中存在 
            while (i.hasNext()) {
                Map.Entry<K,V> e = i.next();
                K key = e.getKey();
                V value = e.getValue();
                	//如果有不相等或是不存在的,立刻返回false
                if (value == null) {
                    if (!(t.get(key)==null && t.containsKey(key)))
                        return false;
                } else {
                    if (!value.equals(t.get(key)))
                        return false;
                }
            }
        } catch (ClassCastException unused)   {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }
        return true;
    }

    /**
     * 返回Map的哈希值,Map中每一個Entry的hashcode相加
     * @see Map#hashCode()
     */
    public synchronized int hashCode() {
        /*
         * 這段代碼檢測了由於哈希表自引用引起的遞歸計算,並阻止了棧溢出。
         * 這段代碼複用了裝載因子loadFactor字段的功能,作爲一個正在計算的標識位,爲了節省空間。
         * 裝載因子爲負說明正在計算hashcode
         */
        int h = 0;
        if (count == 0 || loadFactor < 0)
            return h;  // 返回0

        loadFactor = -loadFactor;  // Mark hashCode computation in progress
        Entry<?,?>[] tab = table;
        for (Entry<?,?> entry : tab) {
            while (entry != null) {
            		//累加哈希值
                h += entry.hashCode();
                entry = entry.next;
            }
        }

        loadFactor = -loadFactor;  // Mark hashCode computation complete
        return h;
    }

    @Override
    public synchronized V getOrDefault(Object key, V defaultValue) {
        V result = get(key);
        return (null == result) ? defaultValue : result;
    }

    @SuppressWarnings("unchecked")
    @Override
    public synchronized void forEach(BiConsumer<? super K, ? super V> action) {
        Objects.requireNonNull(action);     // explicit check required in case
                                            // table is empty.
        final int expectedModCount = modCount;

        Entry<?, ?>[] tab = table;
        for (Entry<?, ?> entry : tab) {
            while (entry != null) {
                action.accept((K)entry.key, (V)entry.value);
                entry = entry.next;

                if (expectedModCount != modCount) {
                    throw new ConcurrentModificationException();
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public synchronized void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
        Objects.requireNonNull(function);     // explicit check required in case
                                              // table is empty.
        final int expectedModCount = modCount;

        Entry<K, V>[] tab = (Entry<K, V>[])table;
        for (Entry<K, V> entry : tab) {
            while (entry != null) {
                entry.value = Objects.requireNonNull(
                    function.apply(entry.key, entry.value));
                entry = entry.next;

                if (expectedModCount != modCount) {
                    throw new ConcurrentModificationException();
                }
            }
        }
    }
    //存在Key就更新,不存在就添加
    @Override
    public synchronized V putIfAbsent(K key, V value) {
        Objects.requireNonNull(value);	//檢測value非空

        // Makes sure the key is not already in the hashtable.
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> entry = (Entry<K,V>)tab[index];
        for (; entry != null; entry = entry.next) {
            if ((entry.hash == hash) && entry.key.equals(key)) {
                V old = entry.value;
                if (old == null) {
                    entry.value = value;
                }
                return old;
            }
        }

        addEntry(hash, key, value, index);
        return null;
    }
    //刪除指定Key-value對
    @Override
    public synchronized boolean remove(Object key, Object value) {
        Objects.requireNonNull(value);

        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> e = (Entry<K,V>)tab[index];
        for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
            if ((e.hash == hash) && e.key.equals(key) && e.value.equals(value)) {
                modCount++;
                if (prev != null) {
                    prev.next = e.next;
                } else {
                    tab[index] = e.next;
                }
                count--;
                e.value = null;
                return true;
            }
        }
        return false;
    }
    //替換舊值爲新值,如果key對應的值不等於舊值(equals),就不替換
    @Override
    public synchronized boolean replace(K key, V oldValue, V newValue) {
        Objects.requireNonNull(oldValue);
        Objects.requireNonNull(newValue);
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> e = (Entry<K,V>)tab[index];
        for (; e != null; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                if (e.value.equals(oldValue)) {
                    e.value = newValue;
                    return true;
                } else {
                    return false;
                }
            }
        }
        return false;
    }
    //替換值,如果不存在key,返回null
    @Override
    public synchronized V replace(K key, V value) {
        Objects.requireNonNull(value);
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> e = (Entry<K,V>)tab[index];
        for (; e != null; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                V oldValue = e.value;
                e.value = value;
                return oldValue;
            }
        }
        return null;
    }
    //如果不存在Key,就添加鍵值對key-value,value通過mappingFunction計算得到 
    @Override
    public synchronized V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
        Objects.requireNonNull(mappingFunction);

        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> e = (Entry<K,V>)tab[index];
        for (; e != null; e = e.next) {
            if (e.hash == hash && e.key.equals(key)) {
                // Hashtable not accept null value
                return e.value;
            }
        }

        V newValue = mappingFunction.apply(key);
        if (newValue != null) {
            addEntry(hash, key, newValue, index);
        }

        return newValue;
    }
    
    //如果存在就替換Key的value值,value通過mappingFunction計算得到,如果計算得到的value爲null,就刪除Key對應的Entry
    @Override
    public synchronized V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(remappingFunction);

        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> e = (Entry<K,V>)tab[index];
        for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
            if (e.hash == hash && e.key.equals(key)) {
                V newValue = remappingFunction.apply(key, e.value);
                	//Hashtable不允許鍵值爲null,刪除Key對應的Entry
                if (newValue == null) {
                    modCount++;
                    if (prev != null) {
                        prev.next = e.next;
                    } else {
                        tab[index] = e.next;
                    }
                    count--;
                } else {
                		//不爲空,替換爲新值
                    e.value = newValue;
                }
                return newValue;
            }
        }
        return null;
    }

    @Override
    public synchronized V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(remappingFunction);

        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> e = (Entry<K,V>)tab[index];
        for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
            if (e.hash == hash && Objects.equals(e.key, key)) {
                V newValue = remappingFunction.apply(key, e.value);
                if (newValue == null) {
                    modCount++;
                    if (prev != null) {
                        prev.next = e.next;
                    } else {
                        tab[index] = e.next;
                    }
                    count--;
                } else {
                    e.value = newValue;
                }
                return newValue;
            }
        }

        V newValue = remappingFunction.apply(key, null);
        if (newValue != null) {
            addEntry(hash, key, newValue, index);
        }

        return newValue;
    }

    @Override
    public synchronized V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(remappingFunction);

        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> e = (Entry<K,V>)tab[index];
        for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
            if (e.hash == hash && e.key.equals(key)) {
                V newValue = remappingFunction.apply(e.value, value);
                if (newValue == null) {
                    modCount++;
                    if (prev != null) {
                        prev.next = e.next;
                    } else {
                        tab[index] = e.next;
                    }
                    count--;
                } else {
                    e.value = newValue;
                }
                return newValue;
            }
        }

        if (value != null) {
            addEntry(hash, key, value, index);
        }

        return value;
    }

    /**
     * 將Hashtable的狀態保存進流中
     * @serialData The <i>capacity</i> of the Hashtable (the length of the
     *             bucket array) is emitted (int), followed by the
     *             <i>size</i> of the Hashtable (the number of key-value
     *             mappings), followed by the key (Object) and value (Object)
     *             for each key-value mapping represented by the Hashtable
     *             The key-value mappings are emitted in no particular order.
     */
    private void writeObject(java.io.ObjectOutputStream s)
            throws IOException {
        Entry<Object, Object> entryStack = null;

        synchronized (this) {
            // Write out the length, threshold, loadfactor
            s.defaultWriteObject();

            // Write out length, count of elements
            s.writeInt(table.length);
            s.writeInt(count);

            // Stack copies of the entries in the table
            for (int index = 0; index < table.length; index++) {
                Entry<?,?> entry = table[index];

                while (entry != null) {
                    entryStack =
                        new Entry<>(0, entry.key, entry.value, entryStack);
                    entry = entry.next;
                }
            }
        }

        // Write out the key/value objects from the stacked entries
        while (entryStack != null) {
            s.writeObject(entryStack.key);
            s.writeObject(entryStack.value);
            entryStack = entryStack.next;
        }
    }

    /**
     * 從流中重建Hashtable(反序列化)
     */
    private void readObject(java.io.ObjectInputStream s)
         throws IOException, ClassNotFoundException
    {
        // Read in the length, threshold, and loadfactor
        s.defaultReadObject();

        // Read the original length of the array and number of elements
        int origlength = s.readInt();
        int elements = s.readInt();

        // Compute new size with a bit of room 5% to grow but
        // no larger than the original size.  Make the length
        // odd if it's large enough, this helps distribute the entries.
        // Guard against the length ending up zero, that's not valid.
        int length = (int)(elements * loadFactor) + (elements / 20) + 3;
        if (length > elements && (length & 1) == 0)
            length--;
        if (origlength > 0 && length > origlength)
            length = origlength;
        table = new Entry<?,?>[length];
        threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
        count = 0;

        // Read the number of elements and then all the key/value objects
        for (; elements > 0; elements--) {
            @SuppressWarnings("unchecked")
                K key = (K)s.readObject();
            @SuppressWarnings("unchecked")
                V value = (V)s.readObject();
            // synch could be eliminated for performance
            reconstitutionPut(table, key, value);
        }
    }

    /**
     * readObject使用的put方法(重建put),因爲put方法支持重寫,並且子類尚未初始化的時候不能調用put方法,所以就提供了reconstitutionPut
     * 它和常規put方法有幾點不同,不檢測rehash,因爲初始元素數目已知。modCount不會自增,因爲我們是在創建一個新的實例。
     * 不需要返回值
     */
    private void reconstitutionPut(Entry<?,?>[] tab, K key, V value)
        throws StreamCorruptedException
    {
        if (value == null) {
            throw new java.io.StreamCorruptedException();
        }
        // 確保Key不在Hashtable中
        // 反序列化過程中不應該 會發生的情況
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
        		//反序列化過程中如果出現Key值重複,拋出異常StreamCorruptedException
            if ((e.hash == hash) && e.key.equals(key)) {
                throw new java.io.StreamCorruptedException();
            }
        }
        // 創建新的Entry.
        @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
        tab[index] = new Entry<>(hash, key, value, e);
        count++;
    }

    /**
     * Hashtable使用單向鏈表Entry解決哈希衝突
     */
    private static class Entry<K,V> implements Map.Entry<K,V> {
        final int hash;	//哈希值,不可變
        final K key;	//關鍵字,不可變
        V value;		//值,可變
        Entry<K,V> next;

        protected Entry(int hash, K key, V value, Entry<K,V> next) {
            this.hash = hash;
            this.key =  key;
            this.value = value;
            this.next = next;
        }
      //返回一個自身的複製對象,淺拷貝,因爲還是引用的當前key和value對象,沒有新建key和value對象
        @SuppressWarnings("unchecked")
        protected Object clone() {
            return new Entry<>(hash, key, value,
                                  (next==null ? null : (Entry<K,V>) next.clone()));
        }
        // Map.Entry 操作
        public K getKey() {
            return key;
        }

        public V getValue() {
            return value;
        }

        public V setValue(V value) {
        		//Hashtable不允許空null值
            if (value == null)
                throw new NullPointerException();

            V oldValue = this.value;
            this.value = value;
            	//返回原值
            return oldValue;
        }
        	//重寫equals方法
        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
            	//類型相同且鍵值(key-value)也相同(equals返回true)
            return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&
               (value==null ? e.getValue()==null : value.equals(e.getValue()));
        }

        public int hashCode() {
        		//hash值只與關鍵字key有關,hashCode需要與值value的hashCode異或
            return hash ^ Objects.hashCode(value);
        }

        public String toString() {
            return key.toString()+"="+value.toString();
        }
    }

    // Enumerations/Iterations的類型
    private static final int KEYS = 0;
    private static final int VALUES = 1;
    private static final int ENTRIES = 2;

    /**
     * Hashtable的枚舉類。實現了迭代器和枚舉接口,但是去掉迭代器方法也能單獨創建實例
     * 這對於避免只通過傳遞枚舉類型來提升容量的意外情況很重要
     */
    private class Enumerator<T> implements Enumeration<T>, Iterator<T> {
        Entry<?,?>[] table = Hashtable.this.table;	//由Hashtable的table數組支持
        int index = table.length;		//table數組的長度
        Entry<?,?> entry = null;		//下一個返回元素
        Entry<?,?> lastReturned = null;	//上一次返回元素
        int type;	//類型:KEYS,Values,Entries

        /**
         * 表明當前枚舉是作爲一個迭代器還是一個枚舉類型(true表示迭代器)
         */
        boolean iterator;

        /**
         * 迭代器認爲Hashtable應該擁有的modCount值。如果期望的不一致,迭代器就檢測到併發修改了
         */
        protected int expectedModCount = modCount;
        /**
         * 構造函數:構造一個類型爲type的迭代器或枚舉集合(iterator爲true表示迭代器)
         * @param type
         * @param iterator
         */
        Enumerator(int type, boolean iterator) {
            this.type = type;
            this.iterator = iterator;
        }
        	//是否還有更多元素
        public boolean hasMoreElements() {
            Entry<?,?> e = entry;
            int i = index;
            Entry<?,?>[] t = table;
            /* 使用本地變量可以使迭代循環的更快*/
            	//上一個返回元素爲空,表明從頭開始返回
            while (e == null && i > 0) {
            		//table數組從後向前遍歷,找到第一個非空元素
                e = t[--i];
            }
            entry = e;
            index = i;
            return e != null;
        }
        	//返回下一個元素
        @SuppressWarnings("unchecked")
        public T nextElement() {
            Entry<?,?> et = entry;
            int i = index;
            Entry<?,?>[] t = table;
            /* 使用本地變量可以使循環迭代得更快 */
            	//上一個返回元素爲空,表明開始返回第一個元素
            while (et == null && i > 0) {
            		//table數組從後向前遍歷,找到第一個非空元素
                et = t[--i];
            }
            entry = et;
            index = i;	//更新Index爲當前返回的最大i
            if (et != null) {
                Entry<?,?> e = lastReturned = entry;	//更新上一個返回元素爲當前即將返回的元素
                entry = e.next;		//更新下一個返回元素爲e.next
                	//類型爲keys則返回Key,爲value則返回value,否則返回Entry
                return type == KEYS ? (T)e.key : (type == VALUES ? (T)e.value : (T)e);
            }
            	//拋出找不到元素異常
            throw new NoSuchElementException("Hashtable Enumerator");
        }

        // 迭代器方法
        public boolean hasNext() {
            return hasMoreElements();
        }
        	//返回下一個元素
        public T next() {
        		//首先檢測併發修改異常
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            	//調用nextElement方法
            return nextElement();
        }
        	//刪除函數,刪除的是上一個返回元素lastReturned
        public void remove() {
        		//只有迭代器類型支持該函數 ,否則拋出不支持該操作異常UnsupportedOperationException()
            if (!iterator)
                throw new UnsupportedOperationException();
            	//如果上一個返回元素爲空,拋出非法狀態異常IllegalStateException
            if (lastReturned == null)
                throw new IllegalStateException("Hashtable Enumerator");
            	//檢測併發修改異常ConcurrentModificationException
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            	//刪除時,需要鎖住全表
            synchronized(Hashtable.this) {
                Entry<?,?>[] tab = Hashtable.this.table;
                	//上一個返回元素的哈希值最高位之外的所有位模table的長度
                int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;

                @SuppressWarnings("unchecked")
                	//獲取該槽位第一個元素
                Entry<K,V> e = (Entry<K,V>)tab[index];
                	//從單鏈表的一端向後遍歷
                for(Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
                		//當前元素即爲上一個返回元素
                    if (e == lastReturned) {
                        modCount++;
                        expectedModCount++;
                        	//刪除上一個元素
                        if (prev == null)
                            tab[index] = e.next;
                        else
                            prev.next = e.next;
                        count--;
                        lastReturned = null;
                        return;
                    }
                }
                throw new ConcurrentModificationException();
            }
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章