[英]Does a HashMap use a HashSet to store its keys?
I'm wondering if a HashMap uses a HashSet to store its keys. 我想知道HashMap是否使用HashSet来存储其密钥。 I would guess it does, because a HashMap would correspond with a HashSet, while a TreeMap would correspond with a TreeSet.
我猜想是的,因为HashMap将与HashSet对应,而TreeMap将与TreeSet对应。
I looked at the source code for the HashMap class, and the method returns an AbstractSet that's implemented by some kind of Iterator. 我查看了HashMap类的源代码,该方法返回了由某种Iterator实现的AbstractSet。
Additionally...when I write 另外...当我写
HashMap map = new HashMap();
if(map.keySet() instanceof HashSet){
System.out.println("true");
}
The above if statement never runs. 上面的if语句永远不会运行。 Now I'm unsure
现在我不确定
Could someone explain how the HashMap stores its keys? 有人可以解释HashMap如何存储其密钥吗?
I'm wondering if a HashMap uses a HashSet to store its keys.
我想知道HashMap是否使用HashSet来存储其密钥。
That would not work too well, because a Set only keeps track of the keys. 这不会太好用,因为Set只跟踪键。 It has no way to store the associated value mapping.
它无法存储关联的值映射。
The opposite (using a Map to store Set elements) is possible, though, and this approach is being used: 但是,可能相反(使用Map存储Set元素),并且正在使用这种方法:
HashSet
is implemented by using a HashMap
(with a dummy value for all keys). HashSet
是通过使用HashMap
(对于所有键都具有虚拟值)实现的。
The set of keys returned by HashMap#keySet
is implemented by a private inner class ( HashMap.KeySet extends AbstractSet
). HashMap#keySet
返回的键集由私有内部类实现( HashMap.KeySet extends AbstractSet
)。
You can study the source for both class, for example on GrepCode: HashMap and HashSet . 您可以研究两个类的源代码,例如在GrepCode上: HashMap和HashSet 。
Could someone explain how the HashMap stores its keys?
有人可以解释HashMap如何存储其密钥吗?
It uses an array of buckets. 它使用一组存储桶。 Each bucket has a linked list of entries.
每个存储桶都有一个链接的条目列表。 See also
也可以看看
The set that is returned by the keySet is backed by the underlying map only. keySet返回的集合仅由基础映射支持。
As per javadoc 根据javadoc
Returns a Set view of the keys contained in this map.
返回此映射中包含的键的Set视图。 The set is backed by the map, so changes to the map are reflected in the set, and vice-versa.
该集合由地图支持,因此对地图的更改会反映在集合中,反之亦然。 If the map is modified while an iteration over the set is in progress (except through the iterator's own remove operation), the results of the iteration are undefined.
如果地图被同时修改了设置的迭代过程中(除了通过迭代器自己的remove操作),则迭代的结果是不确定的。 The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations.
该组支持元件移除,即从地图相应的映射,通过Iterator.remove,Set.remove,的removeAll,retainAll和清除操作。 It does not support the add or addAll operations.
它不支持add或addAll操作。 Blockquote
块引用
HashMap stores keys into buckets. HashMap的存储键进入桶中。 Keys that have same hash code goes into the same bucket.
具有相同哈希码的密钥将进入同一存储桶。 When retrieving value for an key if more than one key is found in the bucket than equals method is used to find the right key and hence the right value.
当如果超过一个关键是在比equals方法桶检索发现一个键值来找到合适的关键,因此正确的价值。
You're actually asking two different questions: 您实际上是在问两个不同的问题:
HashMap
use a HashSet
to store its keys? HashMap
是否使用HashSet
来存储其密钥? HashMap.keySet()
return a HashSet
? HashMap.keySet()
返回HashSet
吗? The answer to both questions is no, and for the same reason, but there's no technical reason preventing either 1. or 2. from being true. 这两个问题的答案都是“否”,并且出于相同的原因,但是没有技术上的理由阻止1.或2.成立。
A HashSet
is actually a wrapper around a HashMap
; HashSet
实际上是HashMap
的包装器; HashSet
has the following member variable: HashSet
具有以下成员变量:
private transient HashMap<E,Object> map;
It populates a PRESENT
sentinel value as the value of the map when an object is added to the set. 当将对象添加到集合中时,它将填充
PRESENT
前哨值作为地图的值。
Now a HashMap
stores it's data in an array of Entry
objects holding the Key, Value pairs: 现在,
HashMap
将其数据存储在包含键,值对的Entry
对象数组中:
transient Entry<K,V>[] table;
And it's keySet()
method returns an instance of the inner class KeySet
: 它的
keySet()
方法返回内部类KeySet
的实例:
public Set<K> keySet() {
Set<K> ks = keySet;
return (ks != null ? ks : (keySet = new KeySet()));
}
private final class KeySet extends AbstractSet<K> {
// minimal Set implementation to access the keys of the map
}
Since KeySet
is a private inner class, as far as you should be concerned it is simply an arbitrary Set
implementation. 由于
KeySet
是一个私有内部类,因此就您所需要的而言,它只是一个任意的Set
实现。
Like I said, there's no reason this has to be the case. 就像我说的,我们没有理由这样具有如此。 You could absolutely implement a
Map
class that used a HashSet
internally, and then have your Map
return a HashSet
from .keySet()
. 您可以绝对实现内部使用
HashSet
的Map
类,然后让Map
从.keySet()
返回HashSet
。 However this would be inefficient and difficult to code; 然而,这将是低效率的并且难以编码。 the existing implementation is both more robust and more efficient than naive
Map
/ Set
implementations. 现有的实现比朴素的
Map
/ Set
实现更加健壮和高效。
Code snippets taken from Oracle JDK 1.7.0_17. 摘自Oracle JDK 1.7.0_17的代码片段。 You can view the source of your version of Java inside the
src.zip
file in your Java install directory. 您可以在Java安装目录中的
src.zip
文件中查看Java版本的源。
Answer is: NO. 答案是:否。
HashMap.keySet()
is a VIEW of the keys contained in this map. HashMap.keySet()
是此映射中包含的键的VIEW 。
The data of the map is stored in Entry[]
table of HashMap
. 映射数据存储在
HashMap
Entry[]
表中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.