新HashMap(int)和番石榴Maps.newHashMapWithExpectedSize(int)之间的区别

时间:2015-05-13 16:47:05

标签: java collections guava

在Java中,您可以创建一个新的HashMap来保存特定数量的项目,如下所示:

Map m = new HashMap(100);

Guava提供Maps.newHashMapWithExpectedSize(int)方法,我希望简单地称之为HashMap(int)。但它不会这样做,而是计算自己的容量并使用它。

为什么newHashMapWithExpectedSize会做自己的事情,为什么我要直接调用new HashMap(int)来使用它?

3 个答案:

答案 0 :(得分:7)

您是否已阅读方法' Javadoc

  

创建一个HashMap实例,具有足够高的"初始容量"它应该保留expectedSize个元素而不会增长。

请注意new HashMap(int)构造函数"初始大小"参数指定存储条目的哈希表的初始大小,这基本上是您不应该关心的实现细节。当哈希表超出地图的加载因子(默认为0.75)时,它将调整大小,这意味着如果您指定初始容量为16,然后向地图添加16个条目,哈希表几乎肯定会被调整大小。

使用Guava的方法,如果指定预期大小为16,然后添加16个条目,则哈希表应该调整大小。

答案 1 :(得分:2)

HashMap构造函数参数是地图的容量,即桶的数量。

因此,如果您将10作为参数传递,并在地图中存储8个键,则将达到重新连接阈值(默认为75%),并且地图将重新散列。

另一方面,传递给newHashMapWithExpectedSize()的参数是地图的预期大小。因此,如果你通过10,Guava将创建一个具有足够桶的地图,以确保在插入10个元素时地图不会重新散列:至少14个桶。

答案 2 :(得分:0)

Guava只是将传递的大小乘以2(以安全的方式)并调用常规的hashmap构造函数。这使得它更稀疏,因此在散列时碰撞更少。

容量计算中的javadoc提到它计算容量的值,以便hashmap在25%到50%之间,这远远超过触发调整大小的阈值。

标准库将预期大小四舍五入到最接近的2的幂并将其分配为大小,然后将调整大小的阈值设置为75%。如果我们随机询问大小,标准库将在50%的情况下调整大小。

如果避免使用阈值是唯一的考虑因素,乘以1.34就足以有足够的空间来避免在填充预期大小的元素时调整大小。

看起来典型的速度与空间交易以及Google工程师的速度更快,而Sun / Oracle工程师更多的空间坚果。