bitset的and/or/xor是就地修改的集合运算,分别对应交集、并集、对称差集;and保留共同位,or合并所有位,xor返回仅属其一的位;需克隆避免原对象被覆盖。

Java 中 BitSet 的 and、or、xor 方法就是专为高效集合运算设计的,直接对应交集、并集、对称差集,不需要手动遍历或转换成其他结构。
and() 对应集合交集
bitSet1.and(bitSet2) 会将 bitSet1 修改为它与 bitSet2 的按位与结果,即只保留两个集合中都存在的元素(索引位同时为 true)。这是标准的交集操作。
- 注意:该方法是“就地修改”,原
bitSet1被覆盖,如需保留原集合,先调用clone()或新建副本 - 若想得到新 BitSet 而不改原对象:
BitSet intersection = (BitSet) bitSet1.clone(); intersection.and(bitSet2); - 底层是长整型数组逐块与运算,时间复杂度接近 O(n/64),远快于遍历比较
or() 对应集合并集
bitSet1.or(bitSet2) 将 bitSet1 更新为两集合的按位或,即所有在任一集合中存在的元素都被置为 true —— 这正是并集语义。
- 同样就地修改;需要保留原值时建议先克隆
- 适合合并多个稀疏集合,比如权限位图合并、标签聚合等场景
- 自动扩容:若
bitSet2的最高位索引更大,or()会自动扩展bitSet1的内部数组
xor() 对应对称差集(非交集)
bitSet1.xor(bitSet2) 返回的是仅属于其中一个集合、不属于交集的元素,即数学上的 (A−B) ∪ (B−A)。虽然不是直接的交/并,但在去重合并、状态翻转等场景很实用。
- 例如:记录两次扫描间新增或删除的 ID(假设 ID 映射为 bit 索引)
- 也可用于“切换”某些位:
flags.xor(mask)相当于对 mask 中为 true 的位置执行布尔非 - 注意:xor 不改变 size() 的逻辑长度,但可能影响后续 cardinality() 计算结果
实际使用小技巧
BitSet 运算是 JVM 层面高度优化的,比基于 HashSet 的 retainAll / addAll 快得多,尤其在元素范围固定且密集(如 0~10000)时优势明显。
- 初始化时尽量预估大小:
new BitSet(expectedMaxIndex + 1)可减少扩容开销 - 避免频繁调用
get(i)遍历 —— 改用stream().forEach()或nextSetBit(fromIndex)迭代更高效 - 跨线程使用需同步;若只读,可放心共享;如需并发修改,考虑
ConcurrentBitSet(第三方)或加锁
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











