Bon*_*eak 4 java memory hashmap inner-classes keyset
这是java.util.HasMap类中的keySet()函数:
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new KeySet();
keySet = ks;
}
return ks;
}
Run Code Online (Sandbox Code Playgroud)
在评论中,它说这个功能
返回此映射中包含的键的{@link Set}视图.该集由地图支持,因此对地图的更改将反映在集中,反之亦然.
因此,我期望KeySet类型的对象,此函数返回的对象将包含对"视图键"的引用.但是,当我查看代码时,KeySet类根本不包含任何字段及其所有超类.
final class KeySet extends AbstractSet<K> {
public final int size() { return size; }
public final void clear() { HashMap.this.clear(); }
public final Iterator<K> iterator() { return new KeyIterator(); }
public final boolean contains(Object o) { return containsKey(o); }
public final boolean remove(Object key) {
return removeNode(hash(key), key, null, false, true) != null;
}
public final Spliterator<K> spliterator() {
return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
}
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下
为了更清楚:
这是打印出键集值的代码示例.虽然KeySet对象保存对包含的地图数据的引用,但是如何准确地输出关键数据而不是地图的其他数据(不是值数据或其他任何数据).什么是告诉这个KeySet对象只保存MapKeys?我在代码中看不到这样的指令.
package com.tutorialspoint;
import java.util.*;
public class HashMapDemo {
public static void main(String args[]) {
// create hash map
HashMap newmap = new HashMap();
// populate hash map
newmap.put(1, "tutorials");
newmap.put(2, "point");
newmap.put(3, "is best");
// get keyset value from map
Set keyset = newmap.keySet();
// check key set values
System.out.println("Key set values are: " + keyset);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
键集值为:[1,2,3]
" 视图 "是一种对象,其数据由不同的对象支持,但以不同的方式提供.在这种情况下,它提供了一个"视图" Map的密钥作为Set.这对用户和性能都有很多好处.
值得注意的是,由于它与支持类共享其数据,因此内存开销非常小 - 它不需要将所有密钥复制到一个全新的密钥中Set.此外,用户无需担心视图与支持结构不同步 - 添加和删除将立即通过视图显示.
因为它KeySet是一个内部类,所以它可以访问其包含类(HashMap)的实例的字段.请注意HashMap.this代码段中的表示法.
size()的return size;是一个参考HashMap的size字段clear()的HashMap.this.clear();通话HashMap的clear()方法(它需要使用HashMap.this引用地图的clear()方法,而不是自己的)contains()代表HashMap的containsKey()方法 - 这不需要HashMap.this因为KeySet没有碰撞containsKey()方法remove()同样代表他们HashMap的removeNode()如果它被声明为final static class KeySet它将是一个静态嵌套类,它不依赖于包含类的实例(它只是一种组织相关类的方式).在这种情况下KeySet需要一个显式HashMap字段,并且需要将有问题的地图传递给构造函数.内部类使这隐含(这是简洁的,但有时令人困惑).
什么是告诉这个KeySet对象只保存MapKeys?
要明确的是,没有这样的指示.一个KeySet实例传递地访问所有的领域和底层映射的方法.但是你的example(System.out.println("Key set values are: " + keyset);)是隐式调用keyset.toString(),(有意)没有实现它来返回map的值.因为KeySetextends AbstractSet(反过来又扩展AbstractCollection).toString()依赖于它KeySet的iterator()实现,它实现了地图键的迭代器,而不是它的值.
| 归档时间: |
|
| 查看次数: |
1019 次 |
| 最近记录: |