以下是的entrySet()的jdk8的源代碼:
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 int size() { return size; }
public final void clear() { HashMap.this.clear(); }
public final Iterator<Map.Entry<K,V>> iterator() {
return new EntryIterator();//get the iterator
}
public final boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Object key = e.getKey();
Node<K,V> candidate = getNode(hash(key), key);
return candidate != null && candidate.equals(e);
}
public final boolean remove(Object o) {
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Object key = e.getKey();
Object value = e.getValue();
return removeNode(hash(key), key, value, true, true) != null;
}
return false;
}
public final Spliterator<Map.Entry<K,V>> spliterator() {
return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0);
}
public final void forEach(Consumer<? super Map.Entry<K,V>> 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);
}
if (modCount != mc)
throw new ConcurrentModificationException();
}
}
}
首先:當我們使用entrySet()方法時,它返回新的EntrySet(),它是EntrySet的一個實例。這個類有一個iterator()方法,可以用於...循環。而iterator()方法返回一個迭代器(類:EntryIterator)
第二:我們讀到最後一類EntryIterator的源代碼:
final class EntryIterator extends HashIterator implements Iterator<Map.Entry<K,V>> {
public final Map.Entry<K,V> next() { return nextNode(); }
}
從代碼中,我們可以看到它實現了next()方法。它返回nextNode();
第三:我們讀nextNode方法的源代碼(它是在HashIterator類):
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() { //when new EntryIterator, this will load data first.
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);
}
}
public final boolean hasNext() {
return next != null;
}
final Node<K,V> nextNode() {
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) {
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();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
current = null;
K key = p.key;
removeNode(hash(key), key, null, false, false);
expectedModCount = modCount;
}
}
根據新對象的順序。它將使用構造函數>基於該順序:對象--->父類--->最後將自己
僅僅指剛,如:新HashIterator(),則新EntryIterator()
當新EntryIterator (),它將在其自身之前使用HashIterator的構造函數 。我們可以看到當我們使用HashIterator的構造函數方法時,它會加載HashMap的數據,當我們使用 時。
而nextNode()方法從這些數據中獲取數據。所以我們可以使用for ...循環來獲取HashMap Object的所有節點。
如果您正在查看'HashMap'代碼,請在'HashMap'中查找內部類'EntrySet'的定義。它實際上是地圖內容的實時視圖。 – khelwood
感謝@khelwood :) 你指的是這個 - 'code' //瀏覽 私人轉移設定> =的entrySet空; 'code' 但..Can你解釋這:) –
user3759177
號,上面寫着'私人final類EntrySet' – khelwood