HashMap的iterator()方法理解

安稳与你 提交于 2019-12-16 14:31:20
HashMap开放3个迭代接口,共同继承了其内部的抽象父类HashIterator:
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以及value的迭代都是Node迭代的属性调用
abstract class HashIterator {    Node<K,V> next;        // next entry to return    Node<K,V> current;     // current entry    int expectedModCount;  // for fast-fail    int index;             // current slot    HashIterator() {        expectedModCount = modCount;        Node<K,V>[] t = table;        current = next = null;        index = 0;        if (t != null && size > 0) { // advance to first entry            do {} while (index < t.length && (next = t[index++]) == null);  // while循环遍历赋值方式,之前在美剧硅谷中看主角使用过,可以不需要do {}语句        }    }    public final boolean hasNext() {        return next != null;    }    final Node<K,V> nextNode() {  // default级别访问权限,仅允许在本类(包)被调用        Node<K,V>[] t;        Node<K,V> e = next;        if (modCount != expectedModCount)            throw new ConcurrentModificationException();        if (e == null)            throw new NoSuchElementException();        if ((next = (current = e).next) == null && (t = table) != null) {  // 当前值变量current            do {} while (index < t.length && (next = t[index++]) == null);  // 可以看出hashmap的遍历顺序:从索引0开始遍历table数组,然后遍历该索引位置的链表或红黑树        }        return e;    }    public final void remove() {        Node<K,V> p = current;        if (p == null)            throw new IllegalStateException();        if (modCount != expectedModCount)            throw new ConcurrentModificationException();        current = null;        K key = p.key;        removeNode(hash(key), key, null, false, false);        expectedModCount = modCount;    }}最后附上正常调用iterator()方法的入口:
public Set<Map.Entry<K,V>> entrySet() {    Set<Map.Entry<K,V>> es;    return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;}
final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
  public final Iterator<Map.Entry<K,V>> iterator() {       return new EntryIterator();  }
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!