位运算与逻辑运算
位运算符
| 运算符 | 运算 | 实例 |
|---|---|---|
| & | 按位与运算 | 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);
}

本文探讨了Java中HashMap容量计算的源码,重点解析了位运算符如按位与(&)、按位或(|)、按位异或(^)以及无符号右移(>>>)在计算过程中的应用。通过位运算确保容量为2的幂次,以优化HashMap的性能。同时,介绍了数值表示的原码、反码和补码概念,以及逻辑运算符(&&、|、!)的工作原理,特别是短路现象在逻辑运算中的影响。
2824

被折叠的 条评论
为什么被折叠?



