阅读JDK中HashMap源码中的代码,HashMap初始化的时候,上来进行一通边界判断,然后接下来你会发现一段奇怪的代码:
/**
* Returns a power of two size for the given target capacity.
*/
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
这一通|= >>>是在玩游戏吗…
当然不是…
这是一堆位运算,不熟悉的同学赶紧去菜鸟教程Java版回炉一下,菜鸟传送门
| = 按位或赋值操作符。 C | = 2等价于C = C | 2
>>> 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 A>>>2得到15即0000 1111
那么这么做的目的是什么呢?
为了炫技啊(好吧,为了快…)
因为HashMap要求它的容量需要时2的整数次幂。上边这一通运算的目的就是为了获得你大于等于预期值,并且为2的整数次幂的容量。
还是回到上面的这一堆位运算,
输入:199
整数,二进制码
198,11000110
231,11100111
255,11111111
255,11111111
255,11111111
255,11111111
x is:256
输入:1999
整数,二进制码
1998,11111001110
2031,11111101111
2047,11111111111
2047,11111111111
2047,11111111111
2047,11111111111
x is:2048
看明白了吧,实际上这一串逻辑是通过位运算把我们预期的值从第一个不为0的位开始,把后面的所有位都设置成1。
也就是获得2n-1的效果。
至于为什么代码的第一行要cap-1,最后取值的时候要+1,是因为上边的位运算在处理2n的值时,会得出2n+1
输入:4
4,100
4,100
6,110
7,111
7,111
7,111
x is:8
还有个问题就是为啥那么好玩的位运算写到16位就不写了呢…
那是因为1+2+4+8+16=31位,已经达到了Int的边界了…
不熟悉的话继续传送门啊^_^ ,菜鸟传送门
int:
int 数据类型是32位、有符号的以二进制补码表示的整数;
最小值是 -2,147,483,648(-2^31);
最大值是 2,147,483,647(2^31 - 1);
一般地整型变量默认为 int 类型;
默认值是 0 ;
例子:int a = 100000, int b = -200000。