一、异或运算:二进制界的"找不同"游戏
异或运算(XOR)就像玩"大家来找茬":
- 规则:两位相同出0,不同出1
- 符号:Java中用
^表示 - 口诀:"同0异1"(相同为0,不同为1)
System.out.println(1 ^ 1); // 输出0 → 相同
System.out.println(0 ^ 1); // 输出1 → 不同
System.out.println(true ^ false); // 输出true → 不同
二、三大神奇特性(异或的"超能力")
1. 自反性:开关原理
int a = 5;
int b = a ^ a; // 结果是0 → 就像开关按两次恢复原状
2. 交换律:密码交换
int x = 10, y = 20;
x = x ^ y;
y = x ^ y; // 神奇的交换!
x = x ^ y; // 不用临时变量
System.out.println(x); // 20
System.out.println(y); // 10
3. 结合律:多重加密
int key1 = 123, key2 = 456;
int data = 789;
int encrypted = data ^ key1 ^ key2; // 双重加密
int decrypted = encrypted ^ key2 ^ key1; // 按顺序解密
三、实战应用场景
1. 简易加密/解密
String text = "Hello";
char secretKey = 'K';
// 加密过程
char[] chars = text.toCharArray();
for(int i=0; i<chars.length; i++){
chars[i] ^= secretKey; // 每个字符与密钥异或
}
String encrypted = new String(chars);
// 解密(同样的操作)
for(int i=0; i<chars.length; i++){
chars[i] ^= secretKey;
}
String decrypted = new String(chars);
2. 数据校验(奇偶校验)
byte[] data = {0x01, 0x02, 0x03};
byte checksum = 0;
for(byte b : data){
checksum ^= b; // 计算校验和
}
System.out.printf("校验和: 0x%02X", checksum);
3. 找单身狗(LeetCode经典题)
// 找出数组中只出现一次的数字(其他都出现两次)
int[] nums = {4, 1, 2, 1, 2};
int single = 0;
for(int num : nums){
single ^= num; // 成对的会抵消
}
System.out.println(single); // 输出4
四、注意事项(容易踩的坑)
-
优先级陷阱:
// 异或优先级低于比较运算符 boolean result = 1 == 2 ^ 2 == 2; // 实际是 (1==2) ^ (2==2) -
类型转换问题:
byte a = 127; byte b = 1; byte c = (byte)(a ^ b); // 必须强制转换 -
布尔运算的妙用:
// 条件1和条件2有且仅有一个成立 if(condition1 ^ condition2){ // 相当于 condition1 != condition2 }
五、性能对比(异or或?)
| 操作 | 示例 | 特点 | ||
|---|---|---|---|---|
| 按位或 | `a | b` | 有1则1 | |
| 按位异或 | a ^ b | 不同则1 | ||
| 逻辑或 | `a | b` | 短路运算 |
🔥 冷知识:异或运算比乘法快10倍以上!
六、趣味扩展:异或画图
用异或实现"橡皮擦"效果(鼠标反复划过会恢复背景):
// 伪代码示例
graphics.setXORMode(Color.WHITE); // 设置异或模式
graphics.drawLine(x1, y1, x2, y2); // 第一次画线
graphics.drawLine(x1, y1, x2, y2); // 第二次在同一位置画会消失!
总结
异或运算就像程序世界的:
- 魔术师:能实现数据交换/加密
- 侦探:能找出异常数据
- 清洁工:能快速清零变量
记住它的核心口诀:"相同为0,不同为1"。下次遇到需要:
- 不用临时变量交换值
- 简单加密数据
- 找数组中唯一数
不妨试试这个神奇的位运算! 🎩✨