Java 位运算对比详解 & | ^ ~

位运算是直接对整数的二进制位进行操作的运算,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。

  • 示例:

    java 复制代码
    int a = 5;  // 二进制: 0101
    int b = 3;  // 二进制: 0011
    int result = a & b; // 二进制: 0001,十进制: 1
    System.out.println(result); // 输出: 1

(2)按位或 |

  • 规则:两个操作数的对应位有一个为 1 时,结果为 1,否则为 0。

  • 示例:

    java 复制代码
    int a = 5;  // 二进制: 0101
    int b = 3;  // 二进制: 0011
    int result = a | b; // 二进制: 0111,十进制: 7
    System.out.println(result); // 输出: 7

(3)按位异或 ^

  • 规则:两个操作数的对应位不同时,结果为 1,否则为 0。

  • 示例:

    java 复制代码
    int a = 5;  // 二进制: 0101
    int b = 3;  // 二进制: 0011
    int result = a ^ b; // 二进制: 0110,十进制: 6
    System.out.println(result); // 输出: 6

(4)按位取反 ~

  • 规则:对操作数的每一位取反(0 变 1,1 变 0)。

  • 示例:

    java 复制代码
    int 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。

  • 示例:

    java 复制代码
    int a = 5;  // 二进制: 0101
    int result = a << 1; // 二进制: 1010,十进制: 10
    System.out.println(result); // 输出: 10

(6)右移 >>

  • 规则:将操作数的二进制位向右移动,左侧补符号位(正数补 0,负数补 1)。

  • 示例:

    java 复制代码
    int a = 5;  // 二进制: 0101
    int result = a >> 1; // 二进制: 0010,十进制: 2
    System.out.println(result); // 输出: 2

(7)无符号右移 >>>

  • 规则:将操作数的二进制位向右移动,左侧补 0。

  • 示例:

    java 复制代码
    int 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 的幂。

    java 复制代码
    int a = 10;
    int multiply = a << 1; // 10 * 2 = 20
    int divide = a >> 1;   // 10 / 2 = 5

(2)权限控制

  • 使用位掩码表示权限:

    java 复制代码
    int 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 中,使用位运算计算数组下标:

    java 复制代码
    int hash = key.hashCode();
    int index = (n - 1) & hash; // n 是数组长度

(4)数据压缩

  • 将多个布尔值压缩到一个整数中:

    java 复制代码
    int flags = 0;
    flags |= (1 << 0); // 设置第 0 位为 1
    flags |= (1 << 1); // 设置第 1 位为 1
    boolean isSet = (flags & (1 << 0)) != 0; // 检查第 0 位是否为 1

4. 注意事项

  • 符号位 :右移 >> 会保留符号位,而无符号右移 >>> 不会。
  • 溢出:左移可能导致溢出,尤其是对负数操作时。
  • 可读性:位运算虽然高效,但代码可读性较差,需谨慎使用。

~~Summary

  • 位运算是对二进制位的直接操作,适用于高效计算、权限控制、哈希计算等场景。
  • Java 提供了丰富的位运算符,包括 &、|、^、~、<<、>>、>>>。
  • 位运算虽然高效,但需注意符号位和溢出问题。
相关推荐
云和数据.ChenGuang6 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
摇滚侠7 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
Cosolar9 小时前
不收费、不加水印、数据归你:我做了个开源的在线简历工具
后端·面试·前端框架
silvamux_9 小时前
10款模型写种草笔记:可发布性、返工来源与成本数据缺口复盘
java·数据库·笔记
步行cgn10 小时前
StringHttpMessageConverter 详解:Spring MVC 中字符串读写的默认转换器
java·spring·mvc
摇滚侠10 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 11
java·笔记·python
小蒜学长10 小时前
基于Spring Boot+Vue3的在线医疗咨询系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·在线问诊·在线医疗咨询系统
Deng桑10 小时前
SpringAI写第一个Agent-把工单循环跑起来
java·agent·工具调用·spring ai
陈随易10 小时前
下载神器!Motrix 停更三年后重写回归
前端·后端·程序员
每天一道题11 小时前
CAP、Raft 与多数派:分布式系统如何达成一致?
分布式·后端·微服务