BitSet.stream() 直接返回所有置位索引的升序 IntStream,时间复杂度 O(k),支持链式操作;而 nextSetBit() 适用于需控制起点或中途跳出的场景,遍历中修改 BitSet 时更可控。

直接用 BitSet.stream() 就能拿到所有值为 true 的位索引组成的 IntStream,无需手动循环或过滤。它按升序返回每个置位位置(从 0 开始),空 BitSet 返回空流,安全且高效。
stream() 的核心特点
该方法不扫描整个底层 long 数组,而是内部优化遍历已设置的位,时间复杂度接近 O(k),k 是实际置位数。返回的流是延迟求值的,支持链式操作,比如:
-
bs.stream().filter(i -> i % 2 == 0).forEach(System.out::println);—— 只处理偶数索引 -
int[] indices = bs.stream().toArray();—— 收集为数组 -
long count = bs.stream().count();—— 统计置位个数(等价于cardinality())
和 nextSetBit() 的区别
stream() 更适合函数式风格、组合操作;nextSetBit(int fromIndex) 更适合需要精细控制遍历起点或中途跳出的场景。例如:
- 想从第 100 位之后找第一个置位 → 用
nextSetBit(100) - 想把所有置位索引转成 List 并去重再排序 →
stream().boxed().collect(Collectors.toList())更自然 - 遍历中需修改 BitSet 本身 →
nextSetBit()更可控(流是快照,不反映后续修改)
常见误用提醒
不要用 length() 或 size() 配合 get(i) 来模拟 stream:
-
length()返回的是最高置位索引 + 1,不是总位数;中间可能有大量未设置的 false 位 -
get(i)越界返回 false 而非异常,容易静默出错 - 逐个
get()判断效率低,是 O(n),而stream()和nextSetBit()都是 O(k)
简单示例
以下代码设置索引 3、7、15 三个位,然后用 stream 打印:
BitSet bs = new BitSet();bs.set(3); bs.set(7); bs.set(15);
bs.stream().forEach(i -> System.out.print(i + " "));
// 输出:3 7 15











