- 知识准备
【无符号右移】
无符号右移运算符“>>>” - 同右移,但是结果全变正数。
【或】
|= 或运算 二进制中只要一个为1就为1
- 正文
在hashMap源码中有相关操作,直接分析源码如下
//返回给定目标容量的2倍幂。将我们传入的容量设置为大于并最接近的2^N
//补位,将原本为0的空位填补为1,最后加1时,
//最高有效位进1,其余变为0,如此就可以取到最近的2的幂
static final int tableSizeFor(int cap) {
//减一后,最右一位肯定和cap的最右一位不同,即一个为0,一个为1
int n = cap - 1;
//(>>>)无符号右移一位,(|)按位或
n |= n >>> 1;
//(>>>)无符号右移两位,(|)按位或
n |= n >>> 2;
//(>>>)无符号右移四位,(|)按位或
n |= n >>> 4;
//(>>>)无符号右移八位,(|)按位或
n |= n >>> 8;
//(>>>)无符号右移十六位,(|)按位或
//这里int占4个字节,32bit,当右移十六位时,已经把左边16位上的1全部移到右边,故此只需要
//左移十六位即可
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
- 实例
* 例1:
* 输入长度为6
* 6-1=5
* 0000 0101 无符号右移一位
* 0000 0010 按位或
* 0000 0111 无符号右移两位
* 0000 0001 按位或
* 0000 0111 无符号右移四位
* 0000 0000 按位或
* 结果不变,同上
* 例2:
* 输入长度为5
* 5-1=4
* 0000 0100
* 0000 0010
* 0000 0110
* 0000 0011
* 0000 0111
* 0000 0000
* 0000 0111
* 后续结果不变