Java位运算符 #

一、位运算符概述 #

位运算符直接对整数的二进制位进行操作,效率极高。

运算符 说明 示例
& 按位与 5 & 3 = 1
| 按位或 5 | 3 = 7
^ 按位异或 5 ^ 3 = 6
~ 按位取反 ~5 = -6
<< 左移 5 << 1 = 10
>> 右移 5 >> 1 = 2
>>> 无符号右移 -5 >>> 1

二、按位运算 #

2.1 按位与(&) #

对应位都为1时结果为1,否则为0。

java
int a = 5;   // 二进制: 0101
int b = 3;   // 二进制: 0011
int c = a & b;  // 结果: 0001 = 1

System.out.println(c);  // 1

/*
  0101 (5)
& 0011 (3)
  ----
  0001 (1)
*/

2.2 按位或(|) #

对应位有一个为1结果就为1。

java
int a = 5;   // 二进制: 0101
int b = 3;   // 二进制: 0011
int c = a | b;  // 结果: 0111 = 7

System.out.println(c);  // 7

/*
  0101 (5)
| 0011 (3)
  ----
  0111 (7)
*/

2.3 按位异或(^) #

对应位不同时结果为1,相同时为0。

java
int a = 5;   // 二进制: 0101
int b = 3;   // 二进制: 0011
int c = a ^ b;  // 结果: 0110 = 6

System.out.println(c);  // 6

/*
  0101 (5)
^ 0011 (3)
  ----
  0110 (6)
*/

异或特性:

  • 任何数与0异或,结果为原数:a ^ 0 = a
  • 任何数与自身异或,结果为0:a ^ a = 0
  • 异或满足交换律和结合律
java
// 交换两个数(不使用临时变量)
int x = 5, y = 3;
x = x ^ y;  // x = 5 ^ 3
y = x ^ y;  // y = (5 ^ 3) ^ 3 = 5
x = x ^ y;  // x = (5 ^ 3) ^ 5 = 3
System.out.println(x + ", " + y);  // 3, 5

2.4 按位取反(~) #

将每一位取反(0变1,1变0)。

java
int a = 5;    // 二进制: 0000...0101
int b = ~a;   // 二进制: 1111...1010 = -6

System.out.println(b);  // -6

// 公式:~a = -(a + 1)

三、移位运算 #

3.1 左移(<<) #

将二进制位向左移动,低位补0。

java
int a = 5;      // 二进制: 0101
int b = a << 1; // 二进制: 1010 = 10
int c = a << 2; // 二进制: 10100 = 20

System.out.println(b);  // 10
System.out.println(c);  // 20

// 左移n位相当于乘以2^n
// 5 << 1 = 5 * 2 = 10
// 5 << 2 = 5 * 4 = 20

3.2 右移(>>) #

将二进制位向右移动,高位补符号位(算术右移)。

java
int a = 10;     // 二进制: 1010
int b = a >> 1; // 二进制: 0101 = 5
int c = a >> 2; // 二进制: 0010 = 2

System.out.println(b);  // 5
System.out.println(c);  // 2

// 右移n位相当于除以2^n(向下取整)
// 10 >> 1 = 10 / 2 = 5
// 10 >> 2 = 10 / 4 = 2

// 负数右移
int d = -10;    // 二进制: 1111...0110
int e = d >> 1; // 二进制: 1111...1011 = -5
System.out.println(e);  // -5

3.3 无符号右移(>>>) #

将二进制位向右移动,高位补0(逻辑右移)。

java
int a = -10;
int b = a >> 1;    // 算术右移,高位补符号位
int c = a >>> 1;   // 无符号右移,高位补0

System.out.println(b);  // -5
System.out.println(c);  // 2147483643

// 正数时 >> 和 >>> 结果相同
int d = 10;
System.out.println(d >> 1);   // 5
System.out.println(d >>> 1);  // 5

四、位运算应用 #

4.1 判断奇偶 #

java
public static boolean isOdd(int n) {
    return (n & 1) == 1;
}

System.out.println(isOdd(5));  // true
System.out.println(isOdd(4));  // false

4.2 交换两数 #

java
public static void swap(int[] arr, int i, int j) {
    if (i != j) {
        arr[i] ^= arr[j];
        arr[j] ^= arr[i];
        arr[i] ^= arr[j];
    }
}

4.3 取绝对值 #

java
public static int abs(int n) {
    int mask = n >> 31;  // 符号位扩展
    return (n ^ mask) - mask;
}

4.4 判断是否为2的幂 #

java
public static boolean isPowerOfTwo(int n) {
    return n > 0 && (n & (n - 1)) == 0;
}

System.out.println(isPowerOfTwo(8));   // true
System.out.println(isPowerOfTwo(6));   // false

4.5 计算二进制中1的个数 #

java
public static int countOnes(int n) {
    int count = 0;
    while (n != 0) {
        n &= (n - 1);  // 清除最低位的1
        count++;
    }
    return count;
}

System.out.println(countOnes(7));   // 3 (111)
System.out.println(countOnes(10));  // 2 (1010)

// Java内置方法
System.out.println(Integer.bitCount(7));  // 3

4.6 权限管理 #

java
public class Permission {
    public static final int READ = 1;     // 0001
    public static final int WRITE = 2;    // 0010
    public static final int EXECUTE = 4;  // 0100
    public static final int DELETE = 8;   // 1000
    
    private int permissions = 0;
    
    // 添加权限
    public void add(int permission) {
        permissions |= permission;
    }
    
    // 移除权限
    public void remove(int permission) {
        permissions &= ~permission;
    }
    
    // 检查权限
    public boolean has(int permission) {
        return (permissions & permission) != 0;
    }
}

// 使用
Permission p = new Permission();
p.add(Permission.READ | Permission.WRITE);
System.out.println(p.has(Permission.READ));    // true
System.out.println(p.has(Permission.EXECUTE)); // false

4.7 快速乘除 #

java
// 乘以2
int a = 5;
int b = a << 1;  // 10

// 除以2
int c = a >> 1;  // 2

// 乘以2的n次方
int d = a << 3;  // 5 * 8 = 40

// 取模(当除数是2的幂时)
int mod = a & 3;  // a % 4

4.8 颜色处理 #

java
// RGB颜色
int color = 0xFF8000;  // 橙色

// 提取RGB分量
int red = (color >> 16) & 0xFF;    // 255
int green = (color >> 8) & 0xFF;   // 128
int blue = color & 0xFF;           // 0

// 合并RGB
int newColor = (red << 16) | (green << 8) | blue;

五、位运算技巧 #

5.1 获取最低位1 #

java
int n = 12;  // 1100
int lowestOne = n & (-n);  // 4 (0100)

5.2 清除最低位1 #

java
int n = 12;  // 1100
int cleared = n & (n - 1);  // 8 (1000)

5.3 翻转最低位1 #

java
int n = 12;  // 1100
int flipped = n ^ (n - 1);  // 0111

5.4 取反特定位 #

java
int n = 12;  // 1100
int mask = 0b0011;
int result = n ^ mask;  // 1111 = 15

六、注意事项 #

6.1 移位范围 #

java
// int类型移位,实际移动位数 = n % 32
int a = 1;
int b = a << 32;  // 相当于 << 0,结果还是1
int c = a << 33;  // 相当于 << 1,结果是2

// long类型移位,实际移动位数 = n % 64
long l = 1L;
long m = l << 64;  // 相当于 << 0,结果还是1

6.2 符号扩展 #

java
byte b = -1;  // 11111111
int i = b;    // 11111111 11111111 11111111 11111111(符号扩展)

// 避免符号扩展
int j = b & 0xFF;  // 00000000 00000000 00000000 11111111 = 255

6.3 优先级 #

java
// 位运算优先级低于算术运算
int a = 5 + 3 & 2;   // (5 + 3) & 2 = 8 & 2 = 0
int b = 5 + (3 & 2); // 5 + 2 = 7

// 建议使用括号明确优先级

七、总结 #

运算符 说明 应用场景
& 按位与 掩码操作、清零、判断奇偶
| 按位或 设置位、权限组合
^ 按位异或 交换、加密、去重
~ 按位取反 取反操作
<< 左移 乘以2的幂
>> 右移 除以2的幂
>>> 无符号右移 无符号除法

位运算要点:

  • 位运算效率高,适合性能敏感场景
  • 注意符号位和移位范围
  • 使用括号明确优先级
  • 常用于权限、状态、算法优化
最后更新:2026-03-26