Reputation: 6240
I'm using a BitSet to represent a time series of data. For example, the first bit represents day 1, the second bit represents day 2, etc.
I am confused when I run the following code because it always returns the length as 0:
BitSet a = new BitSet();
for( int i = 0 ; i < 100 ; i++ ) {
a.set(i, false);
}
System.out.println(a.length());
After some playing around I see its because the values are all false. I set the bit to zero so I would assume it would count in the length and I need it to count. Is there a way to get the count including false and true?
Upvotes: 0
Views: 619
Reputation: 13261
Question:
Is there a way to get the count including false and true?
Answer:
No, not from BitSet
, not reliably! ..you can issue BitSet.size()
, which will give you:
the number of bits currently in this bit set
but size()
(value) won't change, as long as you do bitSet.set(i, false)
resp. bitSet.clear(i)
..for any i
.
...only when i >= size()
and bitSet.set(i/*, true*/)
, it will have effect on (the value of) size()
.
And even if you do:
final int nbits = 1000;
BitSet bs = new BitSet(nbits);
(initialize your bit set with "non default size"), then it is guaranteed, that bs.size() >= nbits
, but not bs.size() == nbits
.
Upvotes: 0
Reputation:
It's not possible using only BitSet
itself - I looked at the implementation, and it simply doesn't store what you want. I can only point out solutions you probably already have in mind:
1) Keep track of the length yourself
2) Use BitSet
from some library (I've found this: https://www.iro.umontreal.ca/~simul/ssj-2/doc/html/umontreal/iro/lecuyer/util/BitVector.html)
3) Extend BitSet
(as pointed out in comments, not the best idea):
import java.util.BitSet;
public class MyBitSet extends BitSet {
int trueLength = 0;
@Override
public void set(int bitIndex) {
trueLength = Math.max(trueLength, bitIndex + 1);
super.set(bitIndex);
}
@Override
public void clear(int bitIndex) {
trueLength = Math.max(trueLength, bitIndex + 1);
super.clear(bitIndex);
}
/* Maybe overload something else... */
/* Or override length */
int getTrueLength() {
return trueLength;
}
}
Upvotes: 0
Reputation: 176
It doesn't seem to contain any method for what you're expecting.
Length returns the size of the BitSet for the last "true" value it has... so:
false, false, false, true, false, false
Will return a length of 4.
Size in the other hand, returns the list max size, it start with 128, but if you pass this mark, it will auto-increase its size.
So, I don't know the actual scenario in which you want to use this, but maybe you could do it with a simple byte
.
Upvotes: 0
Reputation: 14853
Class BitSet have a constructor with the desired number of bits.
Creates a bit set whose initial size is large enough to explicitly represent bits with indices in the range 0 through nbits-1. All bits are initially false.
Returns the number of bits of space actually in use by this BitSet to represent bit values. The maximum element in the set is the size - 1st element.
Returns the number of bits set to true in this BitSet.
BitSet is a compacted set of bit, it seems it's not your need because you have to known the number of bits set to true or false.
My proposal:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main( String[] args ) {
final List<Boolean> bs = new ArrayList<>( 100 );
for( int i = 0; i < 100; ++i ) {
bs.add( Boolean.FALSE );
}
System.err.println( bs.size());
bs.set( 7, Boolean.TRUE );
System.err.println( bs.size());
bs.set( 42, Boolean.TRUE );
System.err.println( bs.size());
}
}
This program echoes 100, 3 times.
Upvotes: 1