HashMap源碼以內部類

/**
* HashMap本身實現的迭代器.主要用來約束對父類成員的引用.同時實現了remove,nextNode,hasNext等必須方法
* 爲了方便子類實現,在nextNode方法中直接返回了Node類型對象.用來直接獲取key與value
*/
abstract class HashIterator {
    /**
    * 下一個節點 
    */
    Node<K,V> next;        // next entry to return
    /**
    * 當前節點 
    */
    Node<K,V> current;     // current entry
    /**
    * 修改計數
    */
    int expectedModCount;  // for fast-fail
    /**
    * 當前下標(對於父級成員變量table來講,它指向桶中的一個槽(slot))
    */
    int index;             // current slot

    /**
    * 構造方法 
    */
    HashIterator() {
        // 緩存修改計數
        expectedModCount = modCount;
        // 緩存桶 
        Node<K,V>[] t = table;
        // 進行置空(這一步是必須的嗎????) 
        current = next = null;
        // 索引置0(爲啥?????) 
        index = 0;
        // 檢查桶是否已經初始化 
        if (t != null && size > 0) { // advance to first entry
            // 提早獲取並保存next
            do {} while (index < t.length && (next = t[index++]) == null);
        }
    }

    public final boolean hasNext() {
        return next != null;
    }

    final Node<K,V> nextNode() {
        // 指向當前桶
        Node<K,V>[] t;
        // 緩存next.準備替換next.同時e做爲結果返回
        Node<K,V> e = next;
        // fast-fail
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
        // next不該爲空
        if (e == null)
            throw new NoSuchElementException();
        // -------------------- 尋找next --------------------
        // 設置current爲e,next爲e.next
        // 判斷next是否爲null
        // 若是爲空,獲取當前桶
        // 判斷桶是否爲空(能走到這裏,說明以前已經在桶中獲取了節點,那桶怎麼回事空的呢?????)
        if ((next = (current = e).next) == null && (t = table) != null) {
            // 上面的next獲取失敗,這裏使用切換槽位的方式尋找下一個next
            do {} while (index < t.length && (next = t[index++]) == null);
        }
        return e;
    }

    public final void remove() {
        Node<K,V> p = current;
        if (p == null)
            throw new IllegalStateException();
        // fast-fail
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
        // 刪除當前迭代其中的current
        current = null;
        // 獲取key
        K key = p.key;
        // 調用父級刪除方法
        // 這裏設置了movable爲false,刪除後不移動節點.這個值只對treeNode生效,去要考證設置成false的做用
        // 貌似是在迭代器中被設置了false
        removeNode(hash(key), key, null, false, false);
        // 更新計數
        expectedModCount = modCount;
    }
}

// --------------------------------  --------------------------------
// 三個繼承了HashIterator的類.實現了分別對Key, Value, Map.Entry的遍歷
final class KeyIterator extends HashIterator
    implements Iterator<K> {
    public final K next() { return nextNode().key; }
}

final class ValueIterator extends HashIterator
    implements Iterator<V> {
    public final V next() { return nextNode().value; }
}

final class EntryIterator extends HashIterator
    implements Iterator<Map.Entry<K,V>> {
    public final Map.Entry<K,V> next() { return nextNode(); }
}

/**
* Key容器.依靠內部類,完成對HashMap成員引用
*/
final class KeySet extends AbstractSet<K> {
    /**
    * 返回hashMap的成員變量size
    * @return 
    */
    public final int size()                 { return size; }
    /**
    * 由於是同名方法,因此只能使用類名.this.MethodName()的方式調用了
    */
    public final void clear()               { HashMap.this.clear(); }
    /**
    * 返回一個內部類key迭代器
    * @return 
    */
    public final Iterator<K> iterator()     { return new KeyIterator(); }
    /**
    * 調用父類方法
    * @param o
    * @return 
    */
    public final boolean contains(Object o) { return containsKey(o); }
    /**
    * 調用父類方法.標記不須要匹配值,刪除後重建
    * @param key
    * @return 
    */
    public final boolean remove(Object key) {
        return removeNode(hash(key), key, null, false, true) != null;
    }
    /**
    * 返回一個內部類keySpl迭代器
    * @return 
    */
    public final Spliterator<K> spliterator() {
        return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
    }
    /**
    * 實現forEach
    * 這裏有個須要注意的地方
    * 對於fail-fast,這個方法會在全部元素迭代完成以後進行,才進行判斷
    * @param action
    */
    public final void forEach(Consumer<? super K> action) {
        Node<K,V>[] tab;
        if (action == null)
            throw new NullPointerException();
        if (size > 0 && (tab = table) != null) {
            int mc = modCount;
            for (int i = 0; i < tab.length; ++i) {
                for (Node<K,V> e = tab[i]; e != null; e = e.next)
                    action.accept(e.key);
            }
            if (modCount != mc)
                throw new ConcurrentModificationException();
        }
    }
}
相關文章
相關標籤/搜索