先贴上实现的源码:
private abstract class HashIterator<E> implements Iterator<E> {
Entry<K,V> next; // next entry to return
int expectedModCount; // For fast-fail
int index; // current slot
Entry<K,V> current; // current entry
HashIterator() {
expectedModCount = modCount;
if (size > 0) { // advance to first entry
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
}
public final boolean hasNext() {
return next != null;
}
final Entry<K,V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if ((next = e.next) == null) {
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
current = e;
return e;
}
public void remove() {
if (current == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Object k = current.key;
current = null;
HashMap.this.removeEntryForKey(k);
expectedModCount = modCount;
}
}
下图是它的逻辑结构:
table数组中的每个元素都指向一个Entry类引用,但其中某些元素可能指向null。每个Entry都有一个next引用,所以整个table相当于一个“链表数组”。
- 在构造器中会找到数组中第一个不是指向null的那个元素,将这个元素存入next中,同时index指向这个 数组元素的下一个下标。
- nextEntry()函数中,next的更新策略如下:首先查看当前“链表”是否已到结尾,若还没到,则next直接指向它的下一个”结点“;若已到”链表“结尾,则需要找到table数组中下一个不是指向空”链表“的那个元素,使next更新为”链表“首结点,同时更新index。
- remove()中的HashMap.this是HashIterator外围类的引用。