HashSet是由HashMap支持的。根据它的JavaDoc:
该类实现了Set接口,由哈希表(实际上是一个HashMap实例)支持
当查看源代码时,我们还可以看到它们之间的关系:
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
因此,
HashSet<E>
由HashMap<E,Object>
支持。对于我们应用程序中的所有HashSets,我们都有一个引用对象PRESENT
,我们在HashMap
中用作值。虽然存储PRESENT
所需的内存可以忽略不计,但我们仍为地图中每个值存储对它的引用。使用
null
代替PRESENT
是否更有效呢?进一步考虑的问题是,如果情况允许使用Map
而不是Set
,我们是否应该完全放弃HashSet
,直接使用HashMap
。触发这些想法的基本问题是我拥有具有以下属性的对象集合:
- 超过30,000个对象的大型集合
- 插入顺序无关紧要
- 高效检查是否包含某项
- 添加新项目到集合中无关紧要。在上述标准的背景下,选择的解决方案应该表现最佳,并尽量减少内存消耗。基于这个基础,数据结构HashSet和HashMap值得考虑。当思考替代方法时,关键问题是:
如何高效地检查包含?
我能想到的唯一答案是使用项哈希计算存储位置。我可能漏掉了什么。还有其他方法吗?
我看了各种问题,虽然它们让我对问题有了一些了解,但并没有完全回答我的问题:
我不想寻求任何替代库或框架建议来解决这个问题,但我想了解是否有其他方法来思考在Collection
中高效地检查元素是否存在。
null
?据我所知,HashMap
中的containsKey
检查get
是否返回null
,因此这会破坏一些东西。 - SalemHashMap
中使用null
作为值? - hotzstnull
和PRESENT
需要相同的内存空间(都需要32位)。但是使用PRESENT
,HashSet的实现更容易。例如,如果使用null
,则HashSet.add()
的实现将更加繁琐。 - ZhekaKozlov