可能重复:
Why does HashSet implementation in Sun Java use HashMap as its backing?
我知道hashset和hashmap是什么 - 非常精通它们。 有一件事让我很困惑。
示例:
Set <String> testing= new HashSet <String>();
现在,如果您在上述语句之后立即使用eclipse进行调试,则在调试器变量选项卡下,您会注意到内部的“测试”集合实现为哈希映射。
为什么它需要一个hashmap,因为sets collection
中没有关键的值对答案 0 :(得分:2)
这是一个实现细节。 HashMap
实际上用作HashSet
的后备存储。 From the docs:
此类实现Set接口,由哈希表(实际上是HashMap实例)支持。它不能保证集合的迭代顺序;特别是,它不保证订单会随着时间的推移保持不变。该类允许null元素。
(强调我的)
答案 1 :(得分:1)
答案恰好在API文档中
“此类实现了Set接口,由哈希表(实际上是HashMap实例)支持。它不保证集合的迭代顺序;特别是,它不保证顺序将保持不变这个类允许null元素。
该类为基本操作(添加,删除,包含和大小)提供恒定的时间性能,假设散列函数在桶之间正确地分散元素。迭代此集合需要的时间与HashSet实例的大小(元素数量)加上后备HashMap实例的“容量”(桶数)之和成比例。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或负载因子太低)非常重要。“
所以你甚至不需要调试器就知道这一点。
回答你的问题:这是一个实施细节。它不需要 来使用HashMap,但它可能只是很好的代码重用。如果你考虑一下,在这种情况下,唯一的区别是一个Set与Map有不同的语义。也就是说,map有get(key)方法,而sets没有。集不允许重复,映射允许重复值,但它们必须位于不同的键下。
使用HashMap作为HashSet的支持可能非常容易,因为你要做的就是在你放入Set的值中使用hashCode(在所有对象上定义)以确定是否欺骗,也就是说,它可能正在做类似
的事情backingHashMap.put(toInsert.hashCode(), toInsert);
将项目插入到Set中。
答案 2 :(得分:0)
在大多数情况下,Set实现为Map的keySet()的包装器。这避免了重复的实现。如果您查看源代码,您将看到它是如何做到的。
你可能会发现方法Collections.newSetFromMap(),它可以用来包装ConcurrentHashMap。
答案 3 :(得分:0)
该类的Javadoc的第一句话说它由HashMap支持:
此类实现Set接口,由哈希表(实际上是HashMap实例)支持。
如果您查看HashSet的源代码,您会看到它在地图中存储的内容是关键是您正在使用的条目,并且该值仅仅是标记Object
(已命名PRESENT
)。
为什么它由HashMap支持?因为这是在(概念)哈希表中存储一组项的最简单方法,并且HashSet不需要重新发明哈希表数据结构的实现。
答案 4 :(得分:0)
标准Java类库使用HashSet
实现HashMap
只是为了方便,它们只需要实现一个数据结构,然后HashSet
将其数据存储在一个数据结构中。 HashMap
以实际设置对象为键,虚拟值(通常为Boolean.TRUE
)为值。
答案 5 :(得分:0)
HashMap已经具备了HashSet所需的所有功能。复制相同的算法是没有意义的。
答案 6 :(得分:0)
它允许您轻松快速地确定对象是否已在集合中。