Java HashMap表的长度为什么是2的倍数?

当为HashMap定义初始大小时:

在这里插入图片描述

会执行这个方法。

在这里插入图片描述

看这个方法的官方注释,说明这个方法会基于所给的自定义容量,返回一个2的倍数的数值。

在这里插入图片描述

所以,如果我们要为HashMap初始化一个容量,那么实际容量也依然会是2的倍数,比如如果定义的容量是3,那么实际上HashMap的容量将会是4。

再看看这个属性,这是HashMap用来存放数据的哈希表。

根据官方解释可以知道,这张表的长度总会是2的倍数。

在这里插入图片描述

为什么HashMap的作者一定要规定table的长度必须是2的倍数?

我们来找找原因。

首先需要知道,对于任何2^n的数,比如8, 16,这些数值的二进制表示总会是100…0的形式,也就是,最高位为1,剩余位全为0。

而对于任何(2^n)-1的数,在二进制下的表现形式总会是1111…1的形式,也就是一串全为1的二进制数值。

现在举两个二进制除法的例子:

比如,Y=101110,且X=1000,则Y / X:

在这里插入图片描述

得到余数:110。

再比如,Y=100110,且X=1000,则Y / X:

在这里插入图片描述

得到余数:110。

观察可知,在二进制运算中,如果除数是2的n倍,那么余数的数值完全可以基于(被除数0~n位 - 除数)计算得到。

即,如果Y=101110,X=1000,那么Y(0~n位) - X=1110-1000=110=Y%X。

更进一步观察可知,被除数0~(n-1)位的这串二进制数值串,其实直接就等同于Y%X的结果。

在这里插入图片描述

通过与一串全为1的二进制数值串做&(且)操作,就能够得到原数值串,所以,Y & (X-1) = 101110 & 111 = 110,110是Y中0~(n-1)的数值串,这个数值串就是Y%X的计算结果。

在这里插入图片描述

所以,正是由于二进制运算的这种特性,HashMap在put进一个新元素到哈希表时,如果哈希表的长度为2的倍数,那么就可以直接通过(n - 1) & hash得到 n%hash的结果了。

在这里插入图片描述

在计算机中,由于位运算的执行效率要比%运算高效很多,所以,通过做位运算,而不是%运算,就能够大大提高对哈希表操作的效率了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值