hashmap容量初始化

创建hashmap对象方法如下:

Map<String, Object> map = new HashMap<String, Object>(size);

在平时coding中,put元素个数很少,加上偷懒。size往往就忽略不写了。

但这次put 15个元素之多..., 我决定要给size赋值了。

赋多少呢?

hashmap默认容量是16,但是当元素达到0.75(也称负载因子)时,即16*0.75=12,hashmap会自动扩容2倍。

那么意味着,size值 = 15 *4 /3 + 1= 21,才不会去触发resize动作。虽然我把size设置为21了,但是jdk在编译优化时,

会把size设为 32,即2的5次方。

也许你注意到了,size最好为2的幂次方,为什么呢? 答应是:保证hash值分布均匀。

因为hashmap的底层数据结构是数组,假如size为16. 那么元素为

hash = (length-1) & hashcode

16 -1 = 15,即二进制1111,和hashcode与操作运算,即hashcode本身,那么保证了hashcode的分布均匀,即保证了hash值的唯一可能性就很大。

那么并不是100%唯一,那么hash值就可能相同,我们叫hash值碰撞,意味着数组中某个元素,比如hash值为2,  2这个元素就以链表形式会保存m个元素,m为桶的深度,即被碰撞的次数。 

查询效率就变低,时间复杂度为 o(1) + o(m),其中,o(1)为hashcode,o(m)为equal比较时间。

 

既然hashmap resize扩展,要重新计算每个元素在数组中的位置,那么肯定是非常消耗性能的。

为此,我单独测试了下。1个是没有设置初始化容量,1个是设置了初始化容量。

多次测试下,运行结果并不是那么的明显。

比如:size为1千万

未初始化下,运行7s左右

初始化下,在6s到12s之间。

这可百思不得其解了。

我想,单从时间这个维度,可能是很难发现差异性。冷静想想自动扩容的实现步骤,设置初始大小肯定有利于性能。

自动扩容内存得重分一次,那在还没有GC前,会导致其实用了很多内存的,而GC也浪费时间,这样复制来复制去,也浪费CPU计算资源。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值