先貼上實現的源碼:
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外圍類的引用。