12

I'm looking for a fast algorithm with gives me all the indexes of the set bits in a BitSet object. This is slow:

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);
}
...

Any help is appreciated!

myborobudur
  • 4,385
  • 8
  • 40
  • 61

6 Answers6

20

No need to use bitSet.cardinality() at all:

for (int i = bitSet.nextSetBit(0); i != -1; i = bitSet.nextSetBit(i + 1)) {
    indexes.add(i);
}
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
7

As specified in 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
     }
 }
Thamme Gowda
  • 11,249
  • 5
  • 50
  • 57
7

As of Java 8 you can use BitSet's stream() method.

IntStream stream()

Returns a stream of indices for which this BitSet contains a bit in the set state.

Community
  • 1
  • 1
Luigi Plinge
  • 50,650
  • 20
  • 113
  • 180
0

Kotlin solution:

val indexes = MutableList<Int>()
var i = bitSet.nextSetBit(0)
while (i != -1) {
    indexes.add(i)
    i = bitSet.nextSetBit(i + 1)
}
naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
0

bitset.toString() will return all the true bit index
like
10010100
{2, 4, 7}
so you can transfer{2, 4, 7}to java list

jacky
  • 649
  • 1
  • 8
  • 22
-1

Change the loop (you increase the complexity to O(N^2) because you call cardinality() in each loop iteration):

for (int e = bitSet.cardinality(), i = 0; i < e; ++i ) {
    indexes.add(nextSetBit);
    nextSetBit = bitSet.nextSetBit(nextSetBit + 1);
}
Durandal
  • 19,919
  • 4
  • 36
  • 70
  • @myborobudur If it didn't help your perceived slowness most likely is *not* caused by the BitSet (either its so small it doesn't matter *or* the autoboxing to Integer overshadows it by far). Use a profiler to measure. – Durandal Mar 13 '13 at 17:02
  • It is better to use the solution that does not call cardinality() – Phil Jan 22 '17 at 17:09