位运算与逻辑运算
位运算符
运算符 | 运算 | 实例 |
---|---|---|
& | 按位与运算 | 6&3 = 2 110 011 |
| | 按位或运算 | 6|3 = 7 |
^ | 按位异或运算 | 6^3 = 5 |
~ | 按位取反运算 | ~3 = -4 |
>> | 右移 | 6>>1 = 3 |
<< | 左移 | 6<<1 = 12 |
>>> | 无符号右移 | 6>>>1 = 3 |
这里分析一段计算HashMap容量的源码
static final int MAXIMUM_CAPACITY = 1 << 30;
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1; // 将最高位的1向后或运算,使它最高两位变成1
n |= n >>> 2; // 最高两位是1了,然后让最高四位变成1
n |= n >>> 4; // ----8位
n |= n >>> 8; // ----16位
n |= n >>> 16; // ----32位
// 所以上面这些就是为了让n的从左到右第一个出现的1后面全部变成1
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
// 最后加1使n变成2的幂次
}
@Test
public void HashTest(){
int size = Mytest.tableSizeFor(52);
System.out.println(size);
}
这里科普一下数值表示
原码:将数字进行二进制转换,int类型为32位,在最前面的一位用来作为符号位,正数为0,负数为1。
反码:将原码的符号位不变,正数不变,负数其他位每位取反,1变0,0变1。
补码:正数不变,负数将原码变为反码后加1。
如:(这里假设数值表示为8位)
数字: 3 -3
原码: 0000 0011 1000 0011
反码: 0000 0011 1111 1100
补码: 0000 0011 1111 1101
逻辑运算
运算符 | 运算 | 示例 |
---|---|---|
&& | 两个条件都为true时返回true | (5>3)&&(3<5) = true |
|| | 两个条件有一个为true时返回true | (5>3)||(5<3) = true |
! | 条件为false时返回true | !(5<3) = true |
逻辑运算的短路
在使用逻辑运算 ||
时,容易出现短路现象。
由于使用 || 运算时,如果第一个条件为true,那么无需计算第二个条件,直接返回true;
而这里要注意的是 |
运算符,它的运算和 ||
有点不一样
@Test
public void operatorTest(){
int x = 1;
// 这里发生了短路
if (++x > 1 || x++ >1){
}
System.out.println(x);
// 这里没有短路
if (++x>2 | x++ > 2){
}
System.out.println(x);
}