java中bitset统计指定范围内set bit数量的推荐方法是调用get(from, to)获取左闭右开子集后使用cardinality();手动按long块计算适合极致性能场景;静态场景可预计算前缀和实现o(1)查询。

Java 中 BitSet 本身没有直接支持“指定范围内 set bit 数量”的内置方法,但可以通过位运算 + 差分技巧高效实现,无需遍历每个 bit。
用 get(from, to) 截取子集再调用 cardinality()
这是最直观、安全且推荐的方式:先用 get(int fromIndex, int toIndex) 获取范围 [from, to) 对应的子 BitSet,再对其调用 cardinality()。
-
fromIndex包含,toIndex不包含(左闭右开),例如get(10, 20)统计第 10~19 位(共 10 位)中为true的数量 - 该方法会自动处理越界(如
toIndex > size()或fromIndex ),返回合理子集 - 时间复杂度取决于子集大小和底层 word 数量,通常比逐位遍历快得多
手动按 long 块计算(适合高频/极致性能场景)
若对性能极其敏感(如百万次查询),可绕过 get() 的对象创建开销,直接操作 BitSet 内部的 long[] words(需通过反射或继承访问,不推荐生产环境轻易使用)。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 定位起始 word 索引:
fromWord = fromIndex >> 6(即fromIndex / 64) - 定位结束 word 索引:
toWord = (toIndex - 1) >> 6 - 对中间完整 word,用
Long.bitCount(word)快速统计 - 对首尾不完整 word,用掩码(mask)提取对应 bit 段再计数,例如:
long mask = (~0L >> (64 - (toIndex % 64))) & (~0L <br> 然后 <code>Long.bitCount(word & mask)
注意边界与空范围处理
务必校验输入范围,避免 from >= to 导致异常或逻辑错误:
if (from >= to) return 0;if (from-
if (to > bitSet.length()) to = bitSet.length();(length()返回最高 set bit 位置 +1) - 也可用
Math.min(to, bitSet.size()),但size()是申请容量,不一定等于实际使用长度
替代方案:预计算前缀和(适合静态 BitSet + 多次查询)
如果 BitSet 构建后不再修改,且需频繁查询不同区间,可预先构建一个前缀和数组 int[] prefix,其中 prefix[i] 表示前 i 位中 set bit 的总数。
- 构建一次 O(n),每次查询 O(1):
prefix[to] - prefix[from] - 适用于 bit 总数可控(如 ≤ 10⁶)、查询密集的场景
- 内存开销略增,但省去重复
get()开销和临时对象分配
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










