在Java中,您可以创建一个新的HashMap
来保存特定数量的项目,如下所示:
Map m = new HashMap(100);
Guava提供Maps.newHashMapWithExpectedSize(int)
方法,我希望简单地称之为HashMap(int)
。但它不会这样做,而是计算自己的容量并使用它。
为什么newHashMapWithExpectedSize
会做自己的事情,为什么我要直接调用new HashMap(int)
来使用它?
答案 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工程师更多的空间坚果。