java的位运算符,如果喜欢研究一些源码的朋友,相信都经常见到,我就拿HashMap做一个简单的代码举例:
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
/**
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
*/
static final int MAXIMUM_CAPACITY = 1 << 30;
由于最近公司写netty的时候用到了位运算符,所以研究的同时来记录一下。
先来一张网图:
我们一个一个来看看
1.>>右移运算符,3<<1,将3向右移动1位
3的二进制表示是11,我们可以添0表示:
0000 0000 0000 0011 (位移前)
0000 0000 0000 0001 (位移后)
向右移动,最右边的舍弃,前面补充0,而01表示的就是1,所以我们代码调试一下
public static void main(String[] args) {
int num = 3;
int index = 1;
System.out.println("数字"+num+"位移前的二进制表示为:"+Integer.toBinaryString(3));
int result = 3>>1;
System.out.println("数字"+num+"位移"+index+"位之后的值为"+result);
}
然后我们看看输出:
数字3位移前的二进制表示为:11
数字3位移1位之后的值为1
Process finished with exit code 0
2.<<左移运算法,3<<1,将3向左位移1为:
0000 0000 0000 0011 (位移前)
0000 0000 0000 0110 (位移后)
向左移动,最左边的舍弃,后面补充0,而0110表示的就是6,所以我们代码调试一下
public static void main(String[] args) {
int num = 3;
int index = 1;
System.out.println("数字"+num+"位移前的二进制表示为:"+Integer.toBinaryString(3));
int result = 3<<1;
System.out.println("数字"+num+"位移"+index+"位之后的值为"+result+","+"二进制表示为:"+Integer.toBinaryString(result));
}
然后我们看看输出:
数字3位移前的二进制表示为:11
数字3位移1位之后的值为6,二进制表示为:110
Process finished with exit code 0
3.那负数的左移和右移呢?
-3左移1位
public static void main(String[] args) {
int num = -3;
int index = 1;
System.out.println("数字"+num+"位移前的二进制表示为:"+Integer.toBinaryString(num));
int result = num<<index;
System.out.println("数字"+num+"位移"+index+"位之后的值为"+result+","+"二进制表示为:"+Integer.toBinaryString(result));
}
打印:
数字-3位移前的二进制表示为:11111111111111111111111111111101
数字-3位移1位之后的值为-6,二进制表示为:11111111111111111111111111111010
Process finished with exit code 0
可以看到左移的正负数都是遵循同样的道理,整体向左移动1为,地位补0
-3右移1位:
数字-3位移前的二进制表示为:11111111111111111111111111111101
数字-3位移1位之后的值为-2,二进制表示为:11111111111111111111111111111110
Process finished with exit code 0
直接看打印,负数右移,高位补充的是1,这就是唯一的区别。
4." >>> " 无符号右移运算符
- 无符号右移,也叫逻辑右移,忽略符号位(无论正负),空位(高位)都以0补齐
- 二进制右移补零操作符,左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充,如value >>> num中,num指定要移位值value 移动的位数
- tip:如果为正数时,>>> 和 >> 结果一致无异
还是代码举个例子:
public static void main(String[] args) {
int num = 3;
int index = 1;
System.out.println("数字"+num+"位移前的二进制表示为:"+Integer.toBinaryString(num));
int result = num>>>index;
System.out.println("数字"+num+"位移"+index+"位之后的值为"+result+","+"二进制表示为:"+Integer.toBinaryString(result));
}
输出:
数字3位移前的二进制表示为:11
数字3位移1位之后的值为1,二进制表示为:1
Process finished with exit code 0
可以看到>>和>>>结果一样
那负数呢?
数字-3位移前的二进制表示为:11111111111111111111111111111101
数字-3位移1位之后的值为2147483646,二进制表示为:1111111111111111111111111111110
Process finished with exit code 0
可以看到,如果我们用-3>>1 后得到的是-2,用无符号右移,得到的就是int的最大值-1。
5.顺便说一下&和|吧,就是或与运算。
0000 0000 0000 0110 6
0000 0000 0000 0011 3
public static void main(String[] args) {
int num = 6;
int num2 = 3;
System.out.println("数字"+num+"的二进制表示为:"+Integer.toBinaryString(num));
System.out.println("数字"+num2+"的二进制表示为:"+Integer.toBinaryString(num2));
int result = num&num2;
System.out.println("数字"+num+"$"+num2+"位之后的值为"+result+","+"二进制表示为:"+Integer.toBinaryString(result));
}
输出:
数字6的二进制表示为:110
数字3的二进制表示为:11
数字6$3位之后的值为2,二进制表示为:10
Process finished with exit code 0
解读一下,&(与)的运算就是两个数,位置上都是1,就记1,其余的记0
再看看|的输出:
数字6的二进制表示为:110
数字3的二进制表示为:11
数字6|3位之后的值为7,二进制表示为:111
Process finished with exit code 0
解读一下,|(或)的运算就是两个数,位置上只要有1个为1,就记1,其余的记0