HashMap的容量为什么一定要是2的幂?

简述HashMap

HashMap是java里面以Key-value存储的一种集合对象,它底层使用的是数组+链表+红黑树的数据结构,它允许key和value为null,是一种无序并且线程不安全的集合对象

面试题

什么是哈希碰撞

在进行Hash算法时,有可能两个不同的原始值在经过哈希运算后得到同样的结果,这样就是哈希碰撞。

HashMap的默认初始容量为什么一定要是2的幂以及扩容也要为2的幂?

当进行HashMap进行put(key,value)时,假设与HashMap的容量为n,首先对元素的key进行hash运算获取哈希值,将得出来的值与n-1进行与运算–> hash & (n - 1)
之后的出来的值就为哈希桶的下标。

n不为2的幂次方时

假设n为17,n-1的二进制为10000,与hash值运算结果如下:
在这里插入图片描述
当n不为2的幂时不同的hash值进行与运算结果可能会出现相同的值,会造成hash碰撞。

n为2的幂次方时

假设n为16,则n-1的二进制为01111,与hash值运算结果如下:
在这里插入图片描述
只有n为2的幂时,不同的hash值,和(n-1)进行位运算后,能够得出不同的索引值,使得添加的元素能够均匀分布在集合中不同的位置上,避免hash碰撞。

思考,可以不用与运算获取哈希桶下标吗?

可以使用(hash值 % n)获取下标值
HashMap容量为n,则哈希桶的下标为0~n-1,。
这样的话就没有了容量必须我2的幂这个限制,但是有以下问题:

  1. 当hash值为负数时,要先将其变为正数(操作是负数+n)
  2. 速度较慢,取余运算速度较低于与运算
总结

HashMap计算添加元素的位置时,使用的位运算,这是特别高效的运算;另外,HashMap的初始容量16,是2的n次幂,扩容也是2倍的形式进行扩容,这样目的就是可以使添加的元素均匀分布在HashMap中的数组上,减少hash碰撞,避免形成链表的结构,使得查询效率降低!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值