位运算是直接对整数的二进制位进行操作的运算,Java 提供了多种位运算符,适用于高效处理二进制数据、优化性能或实现特定算法。以下是 Java 中常用的位运算符及其用法:
1. 位运算符列表
运算符 | 名称 | 描述 | |
---|---|---|---|
& |
按位与(AND) | 两个操作数的对应位都为 1 时,结果为 1,否则为 0。 | |
` | ` | 按位或(OR) | 两个操作数的对应位有一个为 1 时,结果为 1,否则为 0。 |
^ |
按位异或(XOR) | 两个操作数的对应位不同时,结果为 1,否则为 0。 | |
~ |
按位取反(NOT) | 对操作数的每一位取反(0 变 1,1 变 0)。 | |
<< |
左移 | 将操作数的二进制位向左移动,右侧补 0。 | |
>> |
右移(带符号) | 将操作数的二进制位向右移动,左侧补符号位(正数补 0,负数补 1)。 | |
>>> |
无符号右移 | 将操作数的二进制位向右移动,左侧补 0。 |
2. 位运算符详解
(1)按位与 &
-
规则:两个操作数的对应位都为 1 时,结果为 1,否则为 0。
-
示例:
javaint a = 5; // 二进制: 0101 int b = 3; // 二进制: 0011 int result = a & b; // 二进制: 0001,十进制: 1 System.out.println(result); // 输出: 1
(2)按位或 |
-
规则:两个操作数的对应位有一个为 1 时,结果为 1,否则为 0。
-
示例:
javaint a = 5; // 二进制: 0101 int b = 3; // 二进制: 0011 int result = a | b; // 二进制: 0111,十进制: 7 System.out.println(result); // 输出: 7
(3)按位异或 ^
-
规则:两个操作数的对应位不同时,结果为 1,否则为 0。
-
示例:
javaint a = 5; // 二进制: 0101 int b = 3; // 二进制: 0011 int result = a ^ b; // 二进制: 0110,十进制: 6 System.out.println(result); // 输出: 6
(4)按位取反 ~
-
规则:对操作数的每一位取反(0 变 1,1 变 0)。
-
示例:
javaint a = 5; // 二进制: 0000 0000 0000 0000 0000 0000 0000 0101 int result = ~a; // 二进制: 1111 1111 1111 1111 1111 1111 1111 1010,十进制: -6 System.out.println(result); // 输出: -6
(5)左移 <<
-
规则:将操作数的二进制位向左移动,右侧补 0。
-
示例:
javaint a = 5; // 二进制: 0101 int result = a << 1; // 二进制: 1010,十进制: 10 System.out.println(result); // 输出: 10
(6)右移 >>
-
规则:将操作数的二进制位向右移动,左侧补符号位(正数补 0,负数补 1)。
-
示例:
javaint a = 5; // 二进制: 0101 int result = a >> 1; // 二进制: 0010,十进制: 2 System.out.println(result); // 输出: 2
(7)无符号右移 >>>
-
规则:将操作数的二进制位向右移动,左侧补 0。
-
示例:
javaint a = -5; // 二进制: 1111 1111 1111 1111 1111 1111 1111 1011 int result = a >>> 1; // 二进制: 0111 1111 1111 1111 1111 1111 1111 1101,十进制: 2147483645 System.out.println(result); // 输出: 2147483645
3. 位运算的应用场景
(1)高效计算
-
乘除 2 的幂:
-
左移
<<
等价于乘以 2 的幂。 -
右移
>>
等价于除以 2 的幂。
javaint a = 10; int multiply = a << 1; // 10 * 2 = 20 int divide = a >> 1; // 10 / 2 = 5
-
(2)权限控制
-
使用位掩码表示权限:
javaint READ = 1; // 0001 int WRITE = 2; // 0010 int EXECUTE = 4; // 0100 int permissions = READ | WRITE; // 0011(可读可写) boolean canRead = (permissions & READ) != 0; // true boolean canExecute = (permissions & EXECUTE) != 0; // false
(3)哈希计算
-
在
HashMap
中,使用位运算计算数组下标:javaint hash = key.hashCode(); int index = (n - 1) & hash; // n 是数组长度
(4)数据压缩
-
将多个布尔值压缩到一个整数中:
javaint flags = 0; flags |= (1 << 0); // 设置第 0 位为 1 flags |= (1 << 1); // 设置第 1 位为 1 boolean isSet = (flags & (1 << 0)) != 0; // 检查第 0 位是否为 1
4. 注意事项
- 符号位 :右移
>>
会保留符号位,而无符号右移>>>
不会。 - 溢出:左移可能导致溢出,尤其是对负数操作时。
- 可读性:位运算虽然高效,但代码可读性较差,需谨慎使用。
~~Summary
- 位运算是对二进制位的直接操作,适用于高效计算、权限控制、哈希计算等场景。
- Java 提供了丰富的位运算符,包括
&
、|
、^
、~
、<<
、>>
、>>>
。 - 位运算虽然高效,但需注意符号位和溢出问题。