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集合框架中的Hashtable,HashMap,HashSet,哈希表概念