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();
        }
    }
}
相关文章
相关标签/搜索