HashMap之tableSizeFor简单解析
一、源码及提前知识了解
最近看了下HashMap源码,看到tableSizeFor方法,便学习了下。
源码如下图所示:
为了方便我将其粘贴出来,并用main方法调用
tableSizeFor方法中,运用了两个运算符,这里做下简要介绍
1.>>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0。
按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补零。对于正数来说和带符号右移相同,对于负数来说不同。其他结构和>>相似。
2.“|”表示的是或运算,即两个二进制数同位中,只要有一个为1则结果为1,若两个都为1其结果也为1,换句话说就是取交集。
二、举例理解源码
接下来以2个输入值作为例子:
1.出入值为16时
进入代码,cap-1后为15(这里为什么要-1,后面会有总结)
1.1第一次对其进行的位运算
第一次对其进行的位运算
即:
15二进制为0000 1111将其向又移1位变为0000 0111并与0000 1111进行或运算:
![]()
1.2 第二次对其进行位运算
第二次对其进行位运算
即:
n二进制为0000 1111将其向又移2位变为0000 0011并与0000 1111进行或运算
![]()
1.3 第三次对其进行位运算
第三次对其进行位运算
即:
n二进制为0000 1111将其向又移4位变为0000 0000并与0000 1111进行或运算
之后的运算皆为0000 1111与0000 0000进行运算这里不进行赘述
1.4 返回结果
此时n为0000 1111即15,按返回逻辑返回为n+1,即16
![]()
2.出入值为17时
由于对17进行了-1的
2.1第一次对其进行的位运算
第一次对其进行的位运算
即:
16二进制为0001 0000将其向又移1位变为0000 1000并与0001 0000进行或运算:
![]()
2.2第二次对其进行的位运算
第二次对其进行的位运算
即:
n二进制为0001 1000将其向又移2位变为0000 0110并与0001 1000进行或运算:
![]()
2.3第三次对其进行的位运算
第三次对其进行的位运算
即:
n二进制为0001 1110将其向又移4位变为0000 001并与0001 110进行或运算:
之后的运算皆为0001 1111与0000 0000进行运算这里不进行赘述
2.4 返回结果
此时n为0001 1111即31,按返回逻辑返回为n+1,即32
![]()
三 、总结
由此可以看出,上述传入16时,int n = cap – 1;的作用,即按当前算法缺少int n = cap – 1;时,最后输出值则会大一倍,即32,所以要进行int n = cap – 1;的操作,就是为了防止传入值与阀门值相通时,就会被放大一倍的情况发生。
其实只看开头和结尾不难看出,其核心逻辑就是进行补1的操作,即0000 1000 经过运算后变为0000 1111,在最后输出时候在进行加一的操作,变为0001 0000完成计算。