gpt4 book ai didi

java - entrySet() 如何在 HashMap 内部工作?

转载 作者:行者123 更新时间:2023-12-04 00:33:40 27 4
gpt4 key购买 nike

我试图了解 HashMap 中的 entrySet() 函数,但我不确定它是如何工作的,以及在创建新的 EntrySet() 时从何处填充值。

public Set<Map.Entry<K,V>> entrySet() {
return entrySet0();
}

private Set<Map.Entry<K,V>> entrySet0() {
Set<Map.Entry<K,V>> es = entrySet;
return es != null ? es : (entrySet = new EntrySet());
}

最佳答案

以下是jdk8中entrySet()的源码:

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()方法时,它返回new EntrySet(),它是EntrySet的一个实例。并且这个类有一个iterator() 方法,可以在for ...循环中使用。而iterator()方法返回一个iterator(class: EntryIterator)

第二:我们阅读final类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;
}
}

According to the order of new an Object. It will use the constructor function >based on the order: Object ---> Superclass ---> the last will be itself

jsut like : new HashIterator() then new EntryIterator()

when new EntryIterator(), it will use HashIterator's constructor method before itself. We can see it will load the data of HashMap when we use HashIterator's constructor method.

nextNode() 方法从这些数据中获取数据。所以我们可以使用 for ... 循环来获取 HashMap 对象的所有节点。

关于java - entrySet() 如何在 HashMap 内部工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30702183/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com