我们应该使用HashSet吗?

时间:2017-01-28 07:53:38

标签: java collections hashmap hashset

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>。对于我们应用程序中的所有HashSet,我们在PRESENT中使用了一个参考对象HashMap作为值。虽然存储PRESENT所需的内存可以忽略不计,但我们仍会为地图中的每个值存储对它的引用。

使用null代替PRESENT会不会更有效率?如果环境允许使用HashSet代替HashMap,我们应该进一步考虑完全放弃Map并直接使用Set

触发这些想法的基本问题是以下情况:我有一组具有以下属性的对象:

  • 对象的大集合&gt; 30&#39; 000
  • 广告订单不相关
  • 有效检查项目是否包含
  • 向集合添加新项目无关紧要 所选择的解决方案应在上下文中针对上述标准执行最佳,并最小化内存消耗。在此基础上,我想到了数据结构HashSetHashMap。在考虑替代方法时,关键问题是:
  

如何有效地检查集装箱?

我想到的唯一答案是使用items hash来计算存储位置。我可能会在这里遗漏一些东西。还有其他方法吗?

我看过各种各样的问题,确实对这个问题有所了解,但没有悄悄地回答我的问题:

我不是在寻找任何替代库或框架的建议来解决这个问题,但我想了解是否还有另一种方法来考虑Collection中元素的有效容器检查。

2 个答案:

答案 0 :(得分:4)

简而言之,是的,您应该使用HashSet。它可能不是最有效的Set实现,但这几乎不重要,除非您正在处理大量数据。

在这种情况下,我建议使用专门的库。 EnumMaps如果您可以使用枚举,如果您的数据主要是基元,则使用Trove等原始地图,为某些数据类型甚至内存数据库优化的一堆其他数据结构。

不要误会我的意思,我也是喜欢性能调优的人,但是只有在真正需要的时候才能更换内置的数据结构。在大多数情况下,它们的工作非常好。

如果你真的想保存最后一点内存并且不关心插入,你可以做的是使用固定大小的数组,每次排序并进行二进制搜索。但我怀疑它比HashSet更有效。

答案 1 :(得分:0)

Hashtables和HashSets应该完全不同,所以也许两者不应该作为&#34进行比较;这样会更有效&#34;。 hashset更适合数学&#34; set&#34; (例如{1,2,3,4})。它们不包含重复项,只允许一个空值。虽然散列图更像是一个键 - &gt;配对价值体系。它们允许多个空值以及重复,只是不重复键值。我知道这可能是回答哈希表和哈希集之间的区别&#34;但我认为我的观点是他们真的无法进行比较。