Currently with Java version “11.0.3” 2019-04-16 LTS on a Linux host (but would expect 8+ compatibility):
in the context of computing a picture in order to send a binary bitmap to some hardware that only knows a 1-bit depth of display, I am using the BitSet
for the first time and I get some disappointing results: while populating the Bitset
in a loop via the set(int bitIndex, boolean value)
method, the resulting ByteArray
has not always the same size, which does not suit the hardware that always expect the same 1024 bytes payload.
Here is s SSCCCE that illustrates my problem, the result is when I am trying to set a bit at 0, the structure does not grow. On real data I often get arrays way below the expected 1024 (e.g. 592). What I am missing?
8192 iterations pixels has size of 1024 8192 iterations pixels has size of 0 <== WTF?! 8192 iterations pixels has size of 0 <== WTF?!
import java.util.BitSet; public class TestBitset { public static void main(String[] args){ BitSet bs = new BitSet(); int c = 0; for (int band = 0; band <= 7; band++) { for (int x = 0; x <= 127; x++) { for (int bit = 0; bit <= 7; bit++) { boolean val = true; bs.set(band * 128 * 8 + x * 8 + bit, val); c++; } } } System.out.println(c + " iterations"); byte[] pixels = bs.toByteArray(); System.out.println("pixels has size of " + pixels.length); //-------------------------------------------------------- bs = new BitSet(); c = 0; for (int band = 0; band <= 7; band++) { for (int x = 0; x <= 127; x++) { for (int bit = 0; bit <= 7; bit++) { boolean val = false; bs.set(band * 128 * 8 + x * 8 + bit, val); c++; } } } System.out.println(c + " iterations"); pixels = bs.toByteArray(); System.out.println("pixels has size of " + pixels.length); //-------------------------------------------------------- bs = new BitSet(8192); c = 0; for (int band = 0; band <= 7; band++) { for (int x = 0; x <= 127; x++) { for (int bit = 0; bit <= 7; bit++) { boolean val = false /*bit % 7 == 1*/; bs.set(band * 128 * 8 + x * 8 + bit, val); c++; } } } System.out.println(c + " iterations"); pixels = bs.toByteArray(); System.out.println("pixels has size of " + pixels.length); } }
Advertisement
Answer
Quoting the Javadoc of Bitset#toByteArray() for a BitSet s
:
Returns a new byte array containing all the bits in this bit set. More precisely,
if
byte[] bytes = s.toByteArray();
then
bytes.length == (s.length()+7)/8
Note that BitSet#length() is documented as
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.
Now, as all bits in loop 2 and 3 were initialized as false
, s.length() = 0
and
bytes.length
will thus evaluate to 0+7/8
= 0
(int).
Therefore, the observed length of the byte[]
in loop 2 and 3 is correct.