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

时间:2011-03-13 19:29:40

标签: java collections hashtable hashmap hashset

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

我正在使用HashSet,只是为了从整数列表中删除重复的整数。

4 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:2)

对于您声明的问题,您可能还会考虑BitSet

而不是使用HashSet

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

答案 2 :(得分:1)

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

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

答案 3 :(得分: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<Integer> list) {
    Set<Integer> noDupe = new HashSet<Integer>(list.size()); // will end up resizing once, oh well
    for(Integer i : list) noDupe.add(i);
    list.clear();
    list.addAll(noDupe);
}