很多 Java 开发者对位运算的印象只有:面试会问、刷题用过、工作从来不用。
平时写业务代码,我们习惯直接用 if/else、布尔变量、状态字段控制逻辑。但在框架源码、支付系统、权限体系、状态标记、高并发场景中,位运算其实无处不在。
位运算最大的优势:极快、省内存、适合多状态叠加。
今天不讲枯燥原理,只讲 企业真实开发中的位运算落地场景,看完你以后写业务真的能用得上。
一、先快速回顾:Java 常用位运算(极简版)
只记 4 个最常用的,业务开发完全够用:
-
& 与运算 :两个都为 1 才是 1 ------ 用于判断是否包含某状态
-
| 或运算 :有一个是 1 就是 1 ------ 用于添加、叠加状态
-
^ 异或 :相同为 0,不同为 1 ------ 用于状态切换、简单加密、去重
-
~ 取反 :0 变 1、1 变 0 ------ 用于清除状态
位移 << >> 日常业务用得少,本篇只讲 真正落地的场景。
二、业务最常用场景:多状态叠加存储(核心干货)
正常开发中,如果一个功能有多个状态,我们通常会定义多个布尔字段:
是否置顶、是否热门、是否新品、是否推荐、是否审核通过......
字段越多,数据库越乱、扩展越差、查询越慢。
位运算的经典绝杀:用一个 int 存 32 种状态。
定义状态常量
java
// 用 2 的 n 次方定义状态,保证每一位只有一个 1
public static final int STATUS_TOP = 1; // 0001 置顶
public static final int STATUS_HOT = 2; // 0010 热门
public static final int STATUS_NEW = 4; // 0100 新品
public static final int STATUS_RECOMMEND = 8; // 1000 推荐
1、添加状态(叠加状态)使用 | 或运算
java
int status = 0;
// 设置置顶 + 新品
status = status | STATUS_TOP | STATUS_NEW;
2、判断是否包含某个状态 使用 & 与运算
java
// 是否是置顶
if ((status & STATUS_TOP) != 0) {
System.out.println("该商品已置顶");
}
3、移除某个状态 使用 & ~
java
// 取消置顶
status = status & ~STATUS_TOP;
4、切换状态(有则删、无则加)使用 ^ 异或
java
status = status ^ STATUS_HOT;
三、真实业务场景举例(你项目一定用过)
场景 1:文章/商品多标签状态管理
后台商品经常同时具备:新品、热门、置顶、推荐、限时折扣。
如果用多个布尔字段:isTop、isHot、isNew,数据库冗余、查询条件繁琐。
用一个 Integer 字段全部搞定,框架、MyBatis、数据库都友好,扩展无限方便。
场景 2:权限标识控制(框架常用)
很多轻量权限系统不用复杂 RBAC,直接用位运算存用户权限位:
-
查看权限 1
-
新增权限 2
-
编辑权限 4
-
删除权限 8
一个数字就能存储用户所有权限,判断权限只需要 (perm & EDIT) != 0,效率极高。
场景 3:Excel/导入导出状态标记
批量导入数据时,每条数据可能存在:重复、异常、空值、已跳过多种标记,用位运算统一记录异常类型,非常干净。
四、经典面试+源码场景:交换两个数(不用中间变量)
底层源码大量使用异或特性:相同为 0,不同为 1
java
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
实际开发很少用,但 Redis、哈希、加密、校验位 底层大量基于异或思想。
五、高效奇偶判断(比取模更快)
普通写法:num % 2 == 0
位运算写法(更快):(num & 1) == 0
java
// 偶数二进制最后一位一定是 0
if ((num & 1) == 0) {
System.out.println("偶数");
}
六、取整、翻倍、减半(底层高频)
java
n << 1 // 等价于 *2 翻倍
n >> 1 // 等价于 /2 取整减半
JDK、集合扩容、内存计算大量使用位移运算,因为 比乘除运算效率高得多。
七、开发中必须遵守的位运算避坑指南
坑 1:不要用位运算代替所有判断
简单业务状态少,直接布尔值更直观。状态多、叠加多、需要扩展 时再用位运算,不要炫技。
坑 2:状态值必须是 2 的幂次方
如果自定义状态不是 1、2、4、8、16,会出现 状态覆盖、判断错乱,这是新手最大误区。
坑 3:int 最多 32 个状态
int 4 字节 32 位,最多存 32 种状态;状态超多可以用 long(64 位)。
八、总结:位运算真正的工程价值
1、极致省内存:一个数字替代多个布尔字段;
2、速度极快:底层二进制运算,比普通算数、判断更快;
3、适合多状态叠加场景:商品标签、权限、功能开关、任务状态;
4、框架源码高频:Redis、JDK、MyBatis、权限系统随处可见。
位运算不是面试工具,是高级业务开发必备的精简写法。