0

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?

Aubin
  • 14,617
  • 9
  • 61
  • 84
user2924127
  • 6,034
  • 16
  • 78
  • 136
  • Very similar to [this question](https://stackoverflow.com/questions/2854098/java-util-bitset-set-doesnt-work-as-expected) – GBlodgett Feb 04 '19 at 23:26
  • 1
    **Read the documentation**, i.e. the javadoc of [`length()`](https://docs.oracle.com/javase/8/docs/api/java/util/BitSet.html#length--): *"Returns the "logical size" of this BitSet: the index of the highest set bit in the BitSet plus one. **Returns zero if the BitSet contains no set bits**."* – Andreas Feb 04 '19 at 23:40
  • Actually, why do you need this? –  Feb 04 '19 at 23:41

4 Answers4

1

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.

BitSet.size()

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.

BitSet.cardinality

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.

Aubin
  • 14,617
  • 9
  • 61
  • 84
  • 1
    Thanks for the reply, I looked at both these methods and they don't return the number of bits I set. Size() will return 128 in my example and cardinality will return 0 since no bits are set. I am looking to get how many bits I have set to either false or true. So in my example I am looking to return 100. – user2924127 Feb 04 '19 at 23:23
0

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;
  }
}
  • You missed about a dozen overloads for #3. – shmosel Feb 04 '19 at 23:41
  • I think only `set(int fromIndex, int toIndex)` and `clear(int fromIndex, int toIndex)`. –  Feb 04 '19 at 23:44
  • No, there's 3 `clear()` overloads, and 4 `set()` overloads, and `flip()` and `and()` and `or()` etc. etc. And who's to say what they'll add in the next version. This is a classic misuse of inheritance. – shmosel Feb 04 '19 at 23:49
  • These `set`-s call this `set`, so it's fine. For others - agreed, you should override them too. –  Feb 04 '19 at 23:50
  • 1
    Fair point. But that's an implementation detail. There's no guarantee another (parallel or future) implementation will do the same. – shmosel Feb 04 '19 at 23:51
  • I see, agreed. And yeah, delegation would be better. –  Feb 04 '19 at 23:54
0

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.

Osiris Pujols
  • 176
  • 1
  • 6
0

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.

xerx593
  • 12,237
  • 5
  • 33
  • 64