当我阅读JDK的源代码时,我发现有些东西让我很困惑。这就是HashMap跟踪entrySet或值的方式。
下面是HashMap的清晰()代码
public void clear() {
Node<K,V>[] tab;
modCount++;
if ((tab = table) != null && size > 0) {
size = 0;
for (int i = 0; i < tab.length; ++i)
tab[i] = null;
}
}
}我不知道这个方法是如何控制entrySet的。据我所知,entrySet是由HashMap实例缓存的,但我在任何地方都找不到它改变的地方。
上面的代码只是清空了表。以下是HashMap的一些字段。
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
transient Node<K, V>[] table;
transient Set<Map.Entry<K, V>> entrySet;
transient size;
transient int modCount;
int threshold;
final float loadFactor;
// other part
},我不明白。由于clear方法只更改表,它如何影响entrySet.
我使用JUnit测试我的想法。当我调用clear()方法后,HashMap的entrySet是空的。
下面是entrySet()代码
public Set<Map.Entry<K,V>> entrySet() {
Set<Map.Entry<K,V>> es;
return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}如果entrySet不是null,则返回缓存的entrySet,但clear()方法从不更改缓存的entrySet。它怎麽工作?
发布于 2016-03-08 03:13:24
entrySet()只是一个视图。除了(隐式)对HashMap的引用之外,它没有任何内容。它不会创建第二个数据结构,Set方法只是直接访问映射。
请参阅私有HashMap.EntrySet类的实现方式。它是一个内部类,因此它可以看到包含HashMap实例(“拥有”它的对象)。
下面是一个非常简单的例子,它的工作方式完全相同:
interface Foo {
void setFizz(int fizz);
int getFizz();
}
interface Bar {
void setBazz(int bazz);
int getBazz();
// returns a view of this Bar as if it were a Foo
Foo asFoo();
}
class BarImpl implements Bar {
int bazz;
@Override
public int setBazz(int bazz) {
this.bazz = bazz;
}
@Override
public int getBazz() {
return this.bazz;
}
@Override
public Foo asFoo() {
return new Foo() {
@Override
public int setFizz(int fizz) {
BarImpl.this.bazz = fizz;
}
@Override
public int getFizz() {
return BarImpl.this.bazz;
}
};
}
}只有一个int,调用asFoo()只允许我们像访问Foo一样访问Bar。
https://stackoverflow.com/questions/35857974
复制相似问题