Java HashMap.keySet()如何返回键的视图?
下面是java.util.HasMap类中的keySet()函数:Java HashMap.keySet()如何返回键的视图?,java,memory,hashmap,inner-classes,keyset,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; } 输出: 键集值为:[1、2、3] “”是一种对象类型,其数据由不同的对象支持,但提供方式不同。在本例中,它提供了映射键的“
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new KeySet();
keySet = ks;
}
return ks;
}
输出:
键集值为:[1、2、3]
映射
键的“视图”,作为集
。这对用户和性能都有很多好处
值得注意的是,由于它与支持类共享其数据,因此内存开销非常小-它不需要将所有键复制到一个全新的集中。此外,用户不必担心视图与后台结构不同步-添加和删除将通过视图立即可见
KeySet
是一个类,所以它可以访问其包含类(HashMap
)的实例的字段。注意HashMap。这是代码片段中的符号
size()
的返回大小
是对HashMap
的size
字段的引用
clear()
的HashMap.this.clear()
调用HashMap
的clear()
方法(它需要使用HashMap。这个引用映射的clear()
方法,而不是它自己的方法)
contains()
委托HashMap
的containsKey()
方法-这不需要HashMap。这是因为KeySet
没有冲突的containsKey()
方法
remove()
如果它被声明为final static class KeySet
,那么它将是一个静态嵌套类,它不绑定到包含类的实例(这只是组织相关类的一种方式)。在这种情况下,KeySet
需要一个显式的HashMap
字段,并且需要将有问题的映射传递到构造函数中。内部类使其隐式(这很简洁,但有时确实令人困惑)
KeySet
实例可传递地访问备份映射的所有字段和方法。但是,您的示例(System.out.println(“键集值为:“+keyset”);
)隐式调用了keyset.toString()
,这(有意)不是为了返回映射的值而实现的。因为KeySet
扩展了AbstractSet
(这反过来又扩展了AbstractCollection
),所以它依赖于KeySet
的iterator()
实现,该实现在映射的键上提供迭代器,而不是它的值谢谢你的回答。我仍然不理解“它提供了一个地图键的“视图”作为一个集合”的含义。你是说这里提到的“Set”将在包含HashMap键作为元素的内存中创建吗?如果不是,它来自何处?@Bonsaisteak这些关键元素只存储在
HashMap
中。键集
不存储任何内容,它唯一的“字段”是对包含映射的隐式引用。KeySet
的所有方法都使用此隐式引用来访问甚至修改映射的状态。@bonsai是的,Set
反映了Map
的内容(特别是其键)。它不复制或构造新对象-KeySet
只需调用backingMap
。例如,看看contains()
,它只是在映射上调用containsKey()
(HashMap)。这个可以省略,因为KeySet
没有containsKey()
方法)。@shmosel知道KeySet包含对包含映射的引用。然而,我仍然不明白是什么东西指定了它与包含地图键而不是其他数据的连接?@Bonsaisteak你能澄清你的问题吗(也许在编辑原始帖子时,这会给你更多的空间)KeySet
只需作为一个内部类,就可以访问地图的所有数据。因为它的目的是显示有关地图键的信息,所以这就是类实际涉及的全部内容。在此处使用HashMap
和Set
。
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();
}
}
}
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);
}
}