当您知道HashSet中最大可能的元素数时,应使用什么负载因子

当我真正知道HashSet中最大可能的元素数时,我应该使用什么负载因子? 我听说建议使用0.75的默认负载系数,因为它在速度和空间之间提供了良好的性能折衷。 它是否正确 ? 但是,更大的HashSet也会在创建和更多空间上花费更多时间。

我正在使用HashSet,以便从整数列表中删除重复的整数。

我花了一些时间来研究一下载荷因子,并且令人震惊的是,这种设置在实践中的确有些差别。 即使将它设置为像2.0这样的高点也不会减慢速度,也不会节省那么多内存。 只是假装它不存在。 Josh经常后悔曾将它作为一种选择暴露出来。

对于您声明的问题,您可能还会考虑使用BitSet ,而不是使用HashSet

根据整数的范围和稀疏程度,您可能会获得更好的性能和空间特性。

这取决于你的整数。 加载因子的要点是“平衡”散列函数:使用“完美”散列函数,您的加载因子可以是1.0。 但是,如果所讨论的整数值显示任何类型的规律性,则可能导致超过平均的哈希冲突,这会降低地图的效率。 然后,较低的负载因子可以帮助更好地扩展值(在更大的范围内),从而减少散列冲突。

我不会担心使用较低的负载系数所带来的创建时间和额外空间 – 我怀疑你会注意到它们之间的区别(除非你是在硬件有限的平台上,或者你的地图中有数百万个整数 – 然后,大小差异可能变得明显,大致在每百万值的几兆字节的范围内)。

如果您确切知道应该有多少,则应将加载因子设置为1并确保哈希函数以1:1的比例映射。 您可能希望扩展容器以不重新散列哈希。

请注意,这种“确切”的东西往往会随着时间的推移而发生变化,因此您最好只使用普通的容器。 🙂

编辑:我的答案是在我知道它是整数之前。

是的,你最好的选择就是尽可能地离开。 你永远不会注意到差异。

/** * Remove duplicates from a list. * @note This will ALTER the list. * @note This is not thread safe. * @param the list (potentially with duplicates) */ void removeDuplicates(List list) { Set noDupe = new HashSet(list.size()); // will end up resizing once, oh well for(Integer i : list) noDupe.add(i); list.clear(); list.addAll(noDupe); }