JAVA基础集合框架【四】HashMap之源码分析tableSizeFor
文章首发于:clawhub.club
HashMap中的tableSizeFor方法返回给定目标容量的2次幂。
感觉这里面设计的算法真是精妙,数学真是奇妙的学科。
源码如下:
1 | /** |
源码中涉及到无符号右移,位或计算。
位或运算符(|)
运算规则:两个数都转为二进制,然后从高位开始比较,两个数只要有一个为1则为1,否则就为0。
比如:129|128.
129转换成二进制就是10000001,128转换成二进制就是10000000。从高位开始比较得到,得到10000001,即129.
无符号右移(>>>)
运算规则:按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位补0。只针对负数计算,因为对于正数来说这种运算没有意义。
比如:8 >>> 1
8的二进制:1000 ,右移1位:0100,结果为4
即相当于除2的操作。
###源码分析
第一个例子:
* 假设cap=8
* 第一行:n=7 二进制: 0000 0000 0000 0000 0000 0000 0000 0111
* 第二行:n无符号右移1位: 0000 0000 0000 0000 0000 0000 0000 0011
* 与上一步n或: 0000 0000 0000 0000 0000 0000 0000 0111
* n=7 二进制: 0000 0000 0000 0000 0000 0000 0000 0111
* 第三行:n无符号右移2位: 0000 0000 0000 0000 0000 0000 0000 0001
* 与上一步n或: 0000 0000 0000 0000 0000 0000 0000 0111
* n=7 二进制: 0000 0000 0000 0000 0000 0000 0000 0111
* 第四行:n无符号右移4位: 0000 0000 0000 0000 0000 0000 0000 0000
* 与上一步n或: 0000 0000 0000 0000 0000 0000 0000 0111
* n=7 二进制: 0000 0000 0000 0000 0000 0000 0000 0111
* 第五行:n无符号右移8位: 0000 0000 0000 0000 0000 0000 0000 0000
* 与上一步n或: 0000 0000 0000 0000 0000 0000 0000 0111
* n=7 二进制: 0000 0000 0000 0000 0000 0000 0000 0111
* 第五行:n无符号右移16位: 0000 0000 0000 0000 0000 0000 0000 0000
* 与上一步n或: 0000 0000 0000 0000 0000 0000 0000 0111
* n=7 二进制: 0000 0000 0000 0000 0000 0000 0000 0101
* 第六行:n不小于0,也不大于等于1<<30 ,所以 n=n+1=8
第二个例子:
*
* 假设 cap=0100 0000 0000 0000 0000 0000 0000 0000 1个1
* 1: 无符号右移1位:0010 0000 0000 0000 0000 0000 0000 0000
* 或操作:0110 0000 0000 0000 0000 0000 0000 0000 2个1
* 2: 无符号右移2位:0001 1000 0000 0000 0000 0000 0000 0000
* 或操作:0111 1000 0000 0000 0000 0000 0000 0000 4个1
* 3: 无符号右移4位:0000 0111 1000 0000 0000 0000 0000 0000
* 或操作:0111 1111 1000 0000 0000 0000 0000 0000 8个1
* 4: 无符号右移8位:0000 0000 0111 1111 1000 0000 0000 0000
* 或操作:0111 1111 1111 1111 1000 0000 0000 0000 16个1
* 4: 无符号右移16位:0000 0000 0000 0000 0111 1111 1111 1111
* 或操作:0111 1111 1111 1111 1111 1111 1111 1111 31个1
* 5: 结果+1:1000 0000 0000 0000 0000 0000 0000 0000 即2^30;1 << 30。最大值
总结
发现一个规律:无符号右移再位或的最终结果会将二进制首个1的后面所有位都变成1,最后结果再加1,则向前进位(前提不溢出),结果必是2的幂。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ClawHub的技术分享!