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(); }
}
来源:https://www.cnblogs.com/septemberFrost/p/12018033.html