获取 BitSet 中设置位的所有索引

Posted

技术标签:

【中文标题】获取 BitSet 中设置位的所有索引【英文标题】:Get all Indexes of the set bits in a BitSet 【发布时间】:2013-03-01 16:39:33 【问题描述】:

我正在寻找一种快速算法,它可以为我提供 BitSet 对象中设置位的所有索引。 这很慢:

BitSet bitSet = ...
Collection<Integer> indexes = new ArrayList<Integer>(bitSet.cardinality());
int nextSetBit = bitSet.nextSetBit(0);
for (int i = 0; i < bitSet.cardinality(); ++i ) 
    indexes.add(nextSetBit);
    nextSetBit = bitSet.nextSetBit(nextSetBit + 1);

...

感谢任何帮助!

【问题讨论】:

请阅读这篇好文章java-performance.info/bit-sets 【参考方案1】:

根本不需要使用bitSet.cardinality()

for (int i = bitSet.nextSetBit(0); i != -1; i = bitSet.nextSetBit(i + 1)) 
    indexes.add(i);

【讨论】:

【参考方案2】:

如BitSet#nextSetBit(int) javadocs 中所述:

//To iterate over the true bits in a BitSet, use the following loop:
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) 
     // operate on index i here
     if (i == Integer.MAX_VALUE) 
         break; // or (i+1) would overflow
     
 

【讨论】:

【参考方案3】:

从 Java 8 开始,您可以使用 BitSet 的 stream() 方法。

IntStream 流()

返回此 BitSet 包含处于设置状态的位的索引流。

【讨论】:

【参考方案4】:

更改循环(将复杂度增加到 O(N^2),因为您在每次循环迭代中调用 cardinality()):

for (int e = bitSet.cardinality(), i = 0; i < e; ++i ) 
    indexes.add(nextSetBit);
    nextSetBit = bitSet.nextSetBit(nextSetBit + 1);

【讨论】:

@myborobudur 如果它对您感知的缓慢没有帮助,很可能不是由 BitSet 引起的(它太小没关系 i> 到 Integer 的自动装箱远远超过了它)。使用分析器进行测量。 最好使用不调用cardinality()的方案

以上是关于获取 BitSet 中设置位的所有索引的主要内容,如果未能解决你的问题,请参考以下文章

bitset库

java BitSet2

迭代std :: bitset中真实位的有效方法?

Java:计算 java.util.BitSet 中设置的位数

2022-04-24:位集 Bitset 是一种能以紧凑形式存储位的数据结构。 请你实现 Bitset 类。 Bitset(int size) 用 size 个位初始化 Bitset ,所有位都是 0

如何优雅地使用Redis之位图操作