/** * 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(); } } }