HashSet 的迭代成本还取决于支持映射的容量?

Posted

技术标签:

【中文标题】HashSet 的迭代成本还取决于支持映射的容量?【英文标题】:What the iteration cost on a HashSet also depend on the capacity of backing map? 【发布时间】:2012-08-17 16:26:21 【问题描述】:

来自HashSet的JavaDocs:

此类为基本操作提供恒定时间性能 (添加、删除、包含和大小),假设散列函数分散 桶中的元素正确。迭代这个集合 所需时间与 HashSet 实例大小的总和成正比 (元素的数量)加上支持 HashMap 的“容量” 实例(桶的数量)。因此,不要设置是非常重要的 初始容量太高(或负载系数太低)如果 迭代性能很重要

为什么迭代所花费的时间与总和(集合中的元素数量+支持映射的容量)成正比,而不仅仅是集合中的元素数量?

.

【问题讨论】:

如何在不遍历所有空桶的情况下遍历所有元素? 相关:***.com/a/11903357/829571 您也可以check the code 并深入了解幕后情况。 【参考方案1】:

HashSet 使用 HashMap 实现,其中元素是映射键。由于地图有定义数量的桶,可以包含一个或多个元素,迭代需要检查每个桶,是否包含元素。

【讨论】:

那个 hashmap 的值是多少? @Geek 因为值无关紧要,它们只是虚拟对象(或更准确地说,它是一个虚拟对象:private static final Object PRESENT = new Object();)。【参考方案2】:

使用 LinkedHashSet 遵循“链接”条目列表,因此空格的数量无关紧要。通常你不会有一个容量比实际使用的大小多一倍的 HashSet。即使您这样做,扫描一百万个条目,主要是 null 也不会花费太多时间(毫秒)

【讨论】:

我的机器上每 100 万个 null 需要 2 毫秒 ;-) @assylias 听起来不错。不管你做什么,迭代一个 HashSet 都不会很漂亮。如果你想要速度,你真的想做一些查找或排序的集合,你只需要处理几个条目。【参考方案3】:

为什么迭代所花费的时间与总和(数量 集合中的元素+支持映射的容量),而不仅仅是数量 集合本身的元素?

元素分散在由数组支持的底层HashMap 中。 所以不知道哪些桶被占用(但知道有多少元素是完全可用的)。 所以要遍历所有元素所有必须检查桶

【讨论】:

【参考方案4】:

如果您关心的是迭代集合所花费的时间,并且您使用的是 Java 6 或更高版本,请看看这个美丽:

ConcurrentSkipListSet

【讨论】:

以上是关于HashSet 的迭代成本还取决于支持映射的容量?的主要内容,如果未能解决你的问题,请参考以下文章

Java 集合和映射表

Java集合框架中的Hashtable,HashMap,HashSet,哈希表概念

Java集合--set集合

RAM / Disk Memory的访问速度是不是取决于其容量?

LinkedHashSet深入学习

HashSet