BitSet 用 long 数组实现位存储,空间利用率是 boolean[] 的 1/64,支持高效批量位运算,适用于非负整数去重等内存受限场景。

BitSet 是 Java 中一个高效处理位操作的工具类,特别适合在内存受限场景下做海量数据去重、状态标记和布尔集合运算。它底层用 long 数组实现,每个 bit 代表一个 boolean 值,空间利用率是 boolean[] 的 1/64,且位运算(如 and/or/xor)批量执行,性能远超常规集合。
用 BitSet 实现超大规模整数去重
当数据是不重复的非负整数(如用户 ID、日志序号、IP 段映射值),且最大值可控(比如
- 调用 bitSet.set(int index) 标记存在,自动扩容;bitSet.get(int index) 判断是否已存在
- 避免越界:确保 index ≥ 0;若原始数据含负数或过大值,需先哈希映射到 [0, N) 区间(注意哈希冲突需额外校验)
- 示例:统计 1~500 万内出现过的数字,仅需约 625 KB 内存(5000000 / 8 / 1024)
用位运算高效完成集合逻辑操作
BitSet 天然支持交(and)、并(or)、差(andNot)、异或(xor),一次调用即可完成百万级元素的集合运算,比遍历 ArrayList 或 Stream.filter 快一个数量级以上。
- a.and(b):a 变成 a ∩ b;a.or(b):a 变成 a ∪ b
- a.andNot(b):a 变成 a − b(属于 a 但不属于 b)
- a.xor(b):a 变成对称差集(只在 a 或 b 中出现,不同时在)
- 注意:这些方法均原地修改;如需保留原 BitSet,先用 new BitSet(other) 拷贝
与布隆过滤器协同提升去重精度
BitSet 本身不解决哈希冲突——若用哈希映射压缩大范围数据,单个 bit 冲突会导致误判(假阳性)。此时可组合使用:
- 用多个独立 hash 函数 + 多个 BitSet(类似布隆过滤器结构),降低冲突概率
- 或用 BitSet 作“一级快速筛”,确认“肯定不存在”;对“可能存在”的数据再查 HashMap 做精确判定
- 例如:实时日志去重中,先用 BitSet 快速拦截 95% 重复请求,剩余 5% 走轻量级 ConcurrentHashMap,兼顾速度与准确
实用技巧与避坑提醒
BitSet 强大但有隐含约束,忽视易引发 bug:
- 不支持泛型,所有索引必须是 int;超过 Integer.MAX_VALUE(21.47 亿)会抛 IndexOutOfBoundsException
- length() 返回的是最高 set 位的索引 + 1,不是实际容量;size() 才是内部 long 数组长度 × 64
- 序列化时注意:BitSet 默认序列化完整底层数组,空高位也会被写入,体积可能远超有效数据;如需紧凑存储,可用 toByteArray() + 自定义压缩
- 多线程不安全:并发 set/get 需外部同步,或改用 java.util.concurrent.ConcurrentHashMap + 分段 BitSet

















