Skip to content

位运算基础(Java / Android 复习用)

一句话定义

位运算是按二进制每一位做逻辑或移位,用来高效表达标志位、掩码、权限与数值拆合;在 Java 并发与集合底层里很常见,但本身不专属于 HashMap

可运行 Demobitwise-operators-demo · BitwiseOperatorsBasicsDemo.java


为什么要学

优势说明
常数时间、无分支,CPU 直接做位操作
省内存一个 int 可塞 32 个布尔标志
表达力强掩码、权限、协议字段、hash 拌位都靠它
劣势说明
可读性差flags & MASK 不如命名良好的 API 直观
易写错优先级、符号位、>> vs >>> 搞混就翻车
调试难要会看二进制/十六进制才舒服

符号速查

符号名称规则(两位)常见用途
&按位与都是 1 才 1掩码:取出或清零某些位
|按位或有 1 就 1置位:打开某些标志
^按位异或相同 0,不同 1切换位、简单混淆、拌散数据
~按位非0↔1配合掩码做「取反后清零」
<<左移右补 0x << nx × 2^n
>>有符号右移负数左补 1带符号整数除 2(向负无穷取整)
>>>无符号右移左补 0把高位「挪」到低段;无符号语义

& 按位与 — 掩码筛子

比喻:一串 32 个开关,掩码 mask 标出「我只关心这几格」,value & mask 把其它位清零。

java
int READ  = 1 << 0;  // 0001
int WRITE = 1 << 1;  // 0010
int flags = READ | WRITE;

boolean canRead = (flags & READ) != 0;
int lowNibble = value & 0x0F;  // 只保留低 4 位

优劣:判标志、取字段极快;但 if ((flags & X) != 0) 不如枚举类型安全。


|^

java
flags |= READ;           // 打开 READ 位
flags ^= TOGGLE_BIT;     // 翻转某一位

^ 性质: a ^ a = 0a ^ 0 = a — 有时用于无临时变量交换(面试题,工程少用)。


移位:<< / >> / >>>

表达式直观
1 << 38(第 3 位为 1)
x << 2x 乘 4(溢出则截断)
-1 >> 1仍是 -1(符号位填充)
-1 >>> 1大正数(左边补 0)

何时用 >>>:需要把高位无符号地参与低位计算时用 >>>;带符号除法用 >>


Android / Java 工程常见用途

场景典型写法
View 可见性、协议 flagflags & MASK
权限位、能力位|= 置位,&= ~MASK 清位
颜色 ARGB(alpha << 24) | (red << 16) | ...
取低几位下标 / 对齐index & (size - 1)(size 为 2 的幂时)
hash 拌位(集合专题)h ^ (h >>> 16) — 详见 map-concurrency-compare

和后续专题的关系


复习检查题

  1. &&& 有什么区别?

    &按位与(对 int/long 等逐位运算);用在 boolean 上时是逻辑与,但两侧都会求值,不短路。&& 只能用于 boolean,是逻辑与短路:左为 false 时不再算右侧。整数之间不能用 &&;判标志位用 (flags & READ) != 0,不是 flags && READ

  2. -1 >> 4-1 >>> 4 为何不同?

    int-1 二进制为 32 个 1>> 有符号右移,高位补符号位 1,结果仍是 -1>>> 无符号右移,高位补 0,低 28 位为 1,结果是 2684354550x0FFFFFFF)。集合 hash 拌位用 >>>,就是要避免符号位干扰低位。

  3. 如何用位运算判断 flags 是否包含 READ

    READ 为单 bit 时常写 (flags & READ) != 0。若 READ 可能多位组合,用 (flags & READ) == READ 表示「这些位都已打开」。打开/关闭分别用 flags |= READflags &= ~READ

  4. 为什么说「掩码取低 n 位」要求模数是 2 的幂?

    :当 size = 2^n 时,size - 1 的二进制是低 n 位全 1index & (size - 1) 等价于 index % size,且比取模更快。若 size 不是 2 的幂,(size - 1) 不再是连续低位掩码,按位与的结果不等于取模,下标会算错(HashMap 因此要求容量为 2 的幂)。

速记

  • & 筛位,| 开位,^ 翻位,~ 取反。
  • << / >> 乘除 2 的幂;无符号语义用 >>>
  • 位运算快但难读;标志位、掩码、颜色、协议最常见。