Java Hashtable 源碼注釋說明

jopen 10年前發布 | 20K 次閱讀 Hashtable Java開發

package java.util;
import java.io.*;

public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable {

// Hashtable保存的是key-value的數組
// Hashtbale是采用拉鏈法實現的,每一個Entry本質上是一個單向鏈表
// 拉鏈法的本質:當散列表沖突時 ,我們重開一條鏈表。
// transient 序列化時忽略該字段。
// 數組存放的是實體的引用,序列化時必須遍歷該字段逐個實體序列化。
private transient Entry[] table;

// Hashtable中元素的實際數量
private transient int count;

// 擴容臨界值
// 用于判斷是否需要調整Hashtable的容量(threshold=容量*加載因子)
private int threshold;

//加載因子
private float loadFactor;

// Hashtable被改變的次數
private transient int modCount = 0;

//序列版本號
private static final long serialVersionUID = 1421746759512286392L;

//指定容量大小和加載因子的構造方法
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);

            //如果初始化容量等于0,默認設置為1
    if (initialCapacity==0)
        initialCapacity = 1;
    //設置加載因子
            this.loadFactor = loadFactor;
            //創建存儲數組
            table = new Entry[initialCapacity];
            //設置擴容臨界值
            threshold = (int)(initialCapacity * loadFactor);
}

//指定容量大小的構造函數(構造因子默認是0.75f)
public Hashtable(int initialCapacity) {
        this(initialCapacity, 0.75f);
}

//默認構造函數
public Hashtable() {
    // 默認構造函數,指定大的容量大小是11;加載因子是0.75
        this(11, 0.75f);
}

//包含“子map”的構造函數
public Hashtable(Map<? extends K, ? extends V> t) {
        this(Math.max(2*t.size(), 11), 0.75f);
        //將“子Map”的全部元素都添加到Hashtable中
        putAll(t);
}

//返回Hashtable存儲鍵值對的數目
public synchronized int size() {
        return count;
}

// 判斷HashTable是否為空
public synchronized boolean isEmpty() {
        return count == 0;
}

// 返回“所有key”的枚舉對象
public synchronized Enumeration<K> keys() {
            return this.<K>getEnumeration(KEYS);
}

// 返回“所有的value”的枚舉對象
public synchronized Enumeration<V> elements() {
            return this.<V>getEnumeration(VALUES);
}

// 判斷Hashtable是否包含“值(value)”
public synchronized boolean contains(Object value) {
    // Hashtable中“鍵值對”的value不能是null,
  // 若是null的話,拋出異常!
        if (value == null) {
            throw new NullPointerException();
        }


        Entry tab[] = table;
        //從后向前遍歷table數組中的元素(entry)
        for (int i = tab.length ; i-- > 0 ;) {
                //對于每個Entry(單向鏈表),逐個遍歷,判斷節點的值是否等于value
            for (Entry<K,V> e = tab[i] ; e != null ; e = e.next) {
                    if (e.value.equals(value)) {
                        return true;
                    }
            }
        }
        return false;
}

// 判斷Hashtable是否包含“值(value)”
public boolean containsValue(Object value) {
            return contains(value);
}

// 判斷Hashtable是否包含key
public synchronized boolean containsKey(Object key) {
        Entry tab[] = table;
        int hash = key.hashCode();
        //計算索引值
        // % tab.length 是為了防止數組越界
        int index = (hash & 0x7FFFFFFF) % tab.length;
        // 找到“key對應的Entry(鏈表)”,然后在鏈表中找出“哈希值”和“鍵值”與key都相等的元素
        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                    return true;
            }
        }
        return false;
}

// 返回key對應的value,沒有的話返回null
public synchronized V get(Object key) {
            Entry tab[] = table;
            int hash = key.hashCode();
            //計算索引值
            int index = (hash & 0x7FFFFFFF) % tab.length;
            // 找到“key對應的Entry(鏈表)”,然后在鏈表中找出“哈希值”和“鍵值”與key都相等的元素
            for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
                if ((e.hash == hash) && e.key.equals(key)) {
                        return e.value;
                }
            }
            return null;
}

//調整HashTable的長度,將長度變成原來的(2倍+1)
protected void rehash() {
      //臨時保存舊容量,舊數據
            int oldCapacity = table.length;
            Entry[] oldMap = table;

          //創建新容量,新數據
            int newCapacity = oldCapacity * 2 + 1;
            Entry[] newMap = new Entry[newCapacity];

          //更新 修改次數、擴容臨界值、table數組
            modCount++;
            threshold = (int)(newCapacity * loadFactor);
            table = newMap;

          //將舊數組中的數據依次添加到新table數組中
            for (int i = oldCapacity ; i-- > 0 ;) {
                  //添加鏈表
                for (Entry<K,V> old = oldMap[i] ; old != null ; ) {
                        Entry<K,V> e = old;
                        old = old.next;

                        //計算擴容后的索引值
                        int index = (e.hash & 0x7FFFFFFF) % newCapacity;
                        e.next = newMap[index];
                        newMap[index] = e;
                }
            }
}

// 將“key-value”鍵值對添加到Hashtable中
public synchronized V put(K key, V value) {
                // HashTable中不能插入value為null的元素
                if (value == null) {
                    throw new NullPointerException();
                }

                // 若HashTable中已存在鍵為key的鍵值對,
                // 則用新的value替換舊的value
                Entry tab[] = table;
                int hash = key.hashCode();
                //計算索引值
                int index = (hash & 0x7FFFFFFF) % tab.length;
                // 根據索引遍歷對應的Entry鏈表
                for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
                    if ((e.hash == hash) && e.key.equals(key)) {
                                V old = e.value;
                                e.value = value;
                                return old;
                    }
                }

                // 若HashTable中不存在鍵為key的鍵值對
                // 更新修改統計數
                modCount++;
                // 如果HashTable實際容量 > 擴容臨界值 (擴容臨界值=總容量*加載因子)
                // 則調整HashTable的大小
                if (count >= threshold) {
                    // 擴容并按新容量設置hash分布
                    rehash();

                        //更具新容量計算索引
                  tab = table;
                  index = (hash & 0x7FFFFFFF) % tab.length;
                }

                // 將Hashtable中index位置的Entry(鏈表)保存到e中
                Entry<K,V> e = tab[index];
                // 將鍵值對插進entry鏈表中
                tab[index] = new Entry<K,V>(hash, key, value, e);
                // 實際容量+1
                count++;
                return null;
}

// 刪除Hashtable中鍵為key的元素
public synchronized V remove(Object key) {
        Entry tab[] = table;
        int hash = key.hashCode();
        //計算索引值
        int index = (hash & 0x7FFFFFFF) % tab.length;

        // 根據索引遍歷對應的鏈表
        for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
            //找到要刪除的節點并刪除該節點
            if ((e.hash == hash) && e.key.equals(key)) {
                    modCount++;
                    if (prev != null) {
                        prev.next = e.next;
                    } else {
                        tab[index] = e.next;
                    }
                    count--;
                    V oldValue = e.value;
                    e.value = null;
                    return oldValue;
            }
        }
        return null;
}

// 將“Map t”中的全部元素注意添加到Hashtable中
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,并以Object的形式返回。
public synchronized Object clone() {
            try {
                Hashtable<K,V> t = (Hashtable<K,V>) super.clone();
                t.table = new Entry[table.length];
                for (int i = table.length ; i-- > 0 ; ) {
                        t.table[i] = (table[i] != null)
                    ? (Entry<K,V>) 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();
            }
}

public synchronized String toString() {
            int max = size() - 1;
            if (max == -1)
                return "{}";

            StringBuilder sb = new StringBuilder();
            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(", ");
            }
}

    // 獲取Hashtable的枚舉對象
    // 若Hashtable的實際大小為0,則返回“空枚舉類”對象
    // 否則,返回征程的Enumerator的對象。(Enumerator實現了迭代器和枚舉兩個接口)
private <T> Enumeration<T> getEnumeration(int type) {
        if (count == 0) {
            return (Enumeration<T>)emptyEnumerator;
        } else {
            return new Enumerator<T>(type, false);
        }
}

    // 獲取Hashtable的迭代器
    // 若Hashtable的實際大小為0,則返回空迭代器對象
    // 否則,返回正常的Enumerator的對象。(Enumerator實現了迭代器和枚舉兩個接口)
private <T> Iterator<T> getIterator(int type) {
            if (count == 0) {
                return (Iterator<T>) emptyIterator;
            } else {
                return new Enumerator<T>(type, true);
            }
}

// Views

// Hashtable的“key的集合”。它是一個set,意味著沒有重復元素
private transient volatile Set<K> keySet = null;
// Hashtable的“key-value集合”,元素不重復
private transient volatile Set<Map.Entry<K,V>> entrySet = null;
// Hashtable的"key-value集合"。它是一個Collection,有可能有重復
private transient volatile Collection<V> values = null;

// 返回一個被synchronizedSet封裝后的KeySet對象
// synchronizedSet封裝的目的是實現多線程同步(對KeySet的所有方法都添加synchronized)
public Set<K> keySet() {
        if (keySet == null)
            keySet = Collections.synchronizedSet(new KeySet(), this);
        return keySet;
}

    // Hashtable的key的set集合
    // keySet繼承于AbstractSet,所以,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();
    }
}

// 返回一個被synchronizedSet封裝后的EntrySet對象
// synchronizedSet封裝的目的實現多線程同步(對EntrySet的所有方法都添加synchronized)
public Set<Map.Entry<K,V>> entrySet() {
        if (entrySet==null)
            entrySet = Collections.synchronizedSet(new EntrySet(), this);
        return entrySet;
}

    // HashTabled的Entry的set集合
    // EntrySet繼承于AbstractSet,所以,EntrySet中的元素沒有重復的。
private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
    public Iterator<Map.Entry<K,V>> iterator() {
                return getIterator(ENTRIES);
    }

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

            // 是否包含目標對象
    public boolean contains(Object o) {
            // 如果o不是Map.Entry類型 則返回false
        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;

                    //根據索引遍歷鏈表
                    //查找鏈表中是否存在Object o
        for (Entry e = tab[index]; e != null; e = e.next)
            if (e.hash==hash && e.equals(entry))
                return true;
        return false;
    }

            //刪除元素o
    public boolean remove(Object o) {
          // 如果o不是Map.Entry類型 則返回false
        if (!(o instanceof Map.Entry))
            return false;

        Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
                K key = entry.getKey();
        Entry[] tab = table;
        int hash = key.hashCode();
        //計算索引值
        int index = (hash & 0x7FFFFFFF) % tab.length;

                    //遍歷索引值對應的entry鏈表
        for (Entry<K,V> e = tab[index], 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();
    }
}

    // 返回一個被synchronizedCollection封裝后的ValueCollection對象
    // synchronizedCollection封裝的目的是實現多線程同步(對ValueCollection的所有方法都添加synchronized)
public Collection<V> values() {
        if (values==null)
            values = Collections.synchronizedCollection(new ValueCollection(),
                                                    this);
    return values;
}

    // Hashtable的value的Collection集合。
    // ValueCollection繼承于AbstractCollection,所以,ValueCollection中的元素可以重復的。
private class ValueCollection extends AbstractCollection<V> {
    public Iterator<V> iterator() {
            return getIterator(VALUES);
    }
    public int size() {
        return count;
    }
    public boolean contains(Object o) {
        return containsValue(o);
    }
    public void clear() {
        Hashtable.this.clear();
    }
}

// Comparison and hashing

// 覆寫equals()方法
// 若兩個Hashtable的所有key-value鍵值對都相等,則判斷它們兩個相等
public synchronized boolean equals(Object o) {
            if (o == this)
                return true;

            if (!(o instanceof Map))
                return false;

            Map<K,V> t = (Map<K,V>) o;

            if (t.size() != size())
                return false;

          try {
                // 通過迭代器依次取出當前Hashtable的key-value鍵值對
        // 并判斷該鍵值對,存在于Hashtable(o)中。
        // 若不存在,則立即返回false;否則,遍歷完“當前Hashtable”并返回true。
              Iterator<Map.Entry<K,V>> i = entrySet().iterator();
              while (i.hasNext()) {
                      Map.Entry<K,V> e = i.next();
                      K key = e.getKey();
                      V value = e.getValue();
                      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;
}

// 計算Hashtable的哈希值
public synchronized int hashCode() {

    int h = 0;
    // 若 Hashtable的實際大小為0 或者 加載因子<0,則返回0。
    if (count == 0 || loadFactor < 0)
        return h;  // Returns zero

    // 否則,返回“Hashtable中的每個Entry的key和value的異或值 的總和”。
    loadFactor = -loadFactor;  // Mark hashCode computation in progress
    Entry[] tab = table;
    for (int i = 0; i < tab.length; i++)
        for (Entry e = tab[i]; e != null; e = e.next)
            h += e.key.hashCode() ^ e.value.hashCode();
    loadFactor = -loadFactor;  // Mark hashCode computation complete

            return h;
}

// java.io.Serializable的寫入函數
    // 將Hashtable的“總的容量,實際容量,所有的Entry”都寫入到輸出流中
private synchronized void writeObject(java.io.ObjectOutputStream s)
    throws IOException
{
            // Write out the length, threshold, loadfactor
            s.defaultWriteObject();

            // Write out length, count of elements and then the key/value objects
            // 寫入總容量
            s.writeInt(table.length);
            // 寫入實際容量
            s.writeInt(count);
            // 寫入所有實體數據
            for (int index = table.length-1; index >= 0; index--) {
                Entry entry = table[index];

                while (entry != null) {
                        s.writeObject(entry.key);
                        s.writeObject(entry.value);
                        entry = entry.next;
                }
            }
}

// java.io.Serializable的讀取函數:根據寫入方式讀出
// 將Hashtable的“總的容量,實際容量,所有的Entry”依次讀出
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;

                Entry[] table = new Entry[length];
                count = 0;

                // Read the number of elements and then all the key/value objects
                // 讀取所有entry實體數據
                for (; elements > 0; elements--) {
                    K key = (K)s.readObject();
                    V value = (V)s.readObject();
                        // synch could be eliminated for performance
                        reconstitutionPut(table, key, value);
                }
                this.table = table;
}


// 重建Entry[] table數組,只有readObject調用該方法
private void reconstitutionPut(Entry[] tab, K key, V value)
    throws StreamCorruptedException
{
    if (value == null) {
        throw new java.io.StreamCorruptedException();
    }
    // Makes sure the key is not already in the hashtable.
    // This should not happen in deserialized version.
    int hash = key.hashCode();
    int index = (hash & 0x7FFFFFFF) % tab.length;
    for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
        if ((e.hash == hash) && e.key.equals(key)) {
            throw new java.io.StreamCorruptedException();
        }
    }
    // Creates the new entry.
    Entry<K,V> e = tab[index];
    tab[index] = new Entry<K,V>(hash, key, value, e);
    count++;
}

 // Hashtable的Entry節點,它本質上是一個單向鏈表。
 // 因此,我們才能推斷出Hashtable是由拉鏈法實現的散列表
private static class Entry<K,V> implements Map.Entry<K,V> {
        // 哈希值
            int hash;
            K key;
            V value;
            // 指向的下一個Entry,即鏈表的下一個節點
            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;
            }

            protected Object clone() {
                return new Entry<K,V>(hash, key, value,
                          (next==null ? null : (Entry<K,V>) next.clone()));
            }

            // Map.Entry Ops

            public K getKey() {
                return key;
            }

            public V getValue() {
                return value;
            }

            //設置value。若value是null,則拋出異常
            public V setValue(V value) {
                if (value == null)
                        throw new NullPointerException();

                V oldValue = this.value;
                this.value = value;
                return oldValue;
            }

            // 覆蓋equals()方法,判斷兩個Entry是否相等。
    // 若兩個Entry的key和value都相等,則認為它們相等。
            public boolean equals(Object o) {
                if (!(o instanceof Map.Entry))
                return false;
                Map.Entry e = (Map.Entry)o;

                return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&
                   (value==null ? e.getValue()==null : value.equals(e.getValue()));
            }

            public int hashCode() {
                return hash ^ (value==null ? 0 : value.hashCode());
            }

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

}

// Types of Enumerations/Iterations
private static final int KEYS = 0;
private static final int VALUES = 1;
private static final int ENTRIES = 2;

 // Enumerator的作用是提供了“通過elements()遍歷Hashtable的接口” 和 “通過entrySet()遍歷Hashtable的接口”。
 // 因為,它同時實現了 “Enumerator接口”和“Iterator接口”。
private class Enumerator<T> implements Enumeration<T>, Iterator<T> {
        // 指向Hashtable的table
            Entry[] table = Hashtable.this.table;
            // Hashtable的總容量
            int index = table.length;
            Entry<K,V> entry = null;
            Entry<K,V> lastReturned = null;
            int type;

            // Enumerator是 “迭代器(Iterator)” 還是 “枚舉類(Enumeration)”的標志
    // iterator為true,表示它是迭代器;否則,是枚舉類。
            boolean iterator;

            // 在將Enumerator當作迭代器使用時會用到,用來實現fail-fast機制。
            protected int expectedModCount = modCount;

            Enumerator(int type, boolean iterator) {
                this.type = type;
                this.iterator = iterator;
            }

            // 從遍歷table的數組的末尾向前查找,
            // 直到找到不為null的Entry。
            public boolean hasMoreElements() {
                Entry<K,V> e = entry;
                //index初始值為數組長度
                int i = index;
                Entry[] t = table;
                /* Use locals for faster loop iteration */
                //從尾向頭遍歷
                while (e == null && i > 0) {
                        e = t[--i];
                }
                entry = e;
                index = i;
                return e != null;
            }

             // 獲取下一個元素
     // 注意:從hasMoreElements() 和nextElement() 
     // 可以看出“Hashtable的elements()遍歷方式”
     // 首先,從后向前的遍歷table數組。table數組的每個節點都是一個單向鏈表(Entry)。
     // 然后,依次向后遍歷單向鏈表Entry。
            public T nextElement() {
                Entry<K,V> et = entry;
                //index初始值為數組長度
                int i = index;
                Entry[] t = table;
                /* Use locals for faster loop iteration */
                //從后向前遍歷
                while (et == null && i > 0) {
                        et = t[--i];
                }
                entry = et;
                index = i;
                if (et != null) {
                            Entry<K,V> e = lastReturned = entry;
                            entry = e.next;
                            return type == KEYS ? (T)e.key : (type == VALUES ? (T)e.value : (T)e);
                }
                throw new NoSuchElementException("Hashtable Enumerator");
            }

            // 迭代器Iterator的判斷是否存在下一個元素
    // 實際上,它是調用的hasMoreElements()
            public boolean hasNext() {
                return hasMoreElements();
            }

            // 迭代器獲取下一個元素
    // 實際上,它是調用的nextElement()
            public T next() {
                if (modCount != expectedModCount)
                  throw new ConcurrentModificationException();
                return nextElement();
            }

            // 迭代器的remove()接口。
    // 首先,它在table數組中找出要刪除元素所在的Entry,
    // 然后,刪除單向鏈表Entry中的元素
            public void remove() {
                  if (!iterator)
                        throw new UnsupportedOperationException();
                  if (lastReturned == null)
                        throw new IllegalStateException("Hashtable Enumerator");
                  if (modCount != expectedModCount)
                        throw new ConcurrentModificationException();

                  synchronized(Hashtable.this) {
                            Entry[] tab = Hashtable.this.table;
                            //刪除lastReturned,計算索引
                            int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;

                            //遍歷列表刪除
                            for (Entry<K,V> e = tab[index], 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();
                    }
                }
          }


private static Enumeration emptyEnumerator = new EmptyEnumerator();
private static Iterator emptyIterator = new EmptyIterator();

// 空枚舉類
// 當Hashtable的實際大小為0;此時,
// 又要通過Enumeration遍歷Hashtable時,返回的是“空枚舉類”的對象。
private static class EmptyEnumerator implements Enumeration<Object> {

            EmptyEnumerator() {
            }

            // 空枚舉類的hasMoreElements() 始終返回false
            public boolean hasMoreElements() {
                return false;
            }

            // 空枚舉類的nextElement() 拋出異常
            public Object nextElement() {
                throw new NoSuchElementException("Hashtable Enumerator");
            }
}


// 空迭代器
// 當Hashtable的實際大小為0;此時,
// 又要通過迭代器遍歷Hashtable時,返回的是“空迭代器”的對象。
private static class EmptyIterator implements Iterator<Object> {

            EmptyIterator() {
            }

            //空迭代器的hasNext,始終返回false
            public boolean hasNext() {
                return false;
            }

            //空迭代器的next,拋出異常
            public Object next() {
                throw new NoSuchElementException("Hashtable Iterator");
            }

            public void remove() {
                throw new IllegalStateException("Hashtable Iterator");
            }

}

}</pre>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!