BitSet
Bits are efficient. Imagine we need to store many true or false values. Using bits, not bytes, saves 7 bits per value—and these savings can add up.
Some programs written in Java may use excess memory—with a collection like BitSet
, we can improve performance in these programs. Sometimes the results are dramatic.
We begin with a simple example of BitSet
: we set two bits, at positions 10 and 100. Then we get some bits. Position 5 is false, but 10 and 100 are true.
set()
function sets a bit to true (or 1). To set a bit to zero, please use the clear method or specify false in set.get()
function returns a boolean indicating the value of the bit. True is 1 and false is 0.import java.util.BitSet; public class Program { public static void main(String[] args) { // Set two bits in a BitSet. BitSet b = new BitSet(); b.set(10); b.set(100); // Get values of these bit positions. boolean bit1 = b.get(5); boolean bit2 = b.get(10); boolean bit3 = b.get(100); System.out.println(bit1); System.out.println(bit2); System.out.println(bit3); } }false true true
This method makes some programs simpler. It changes the value of a 0 bit to 1, and the value of a 1 bit to zero. By default in BitSet
, a bit is zero.
import java.util.BitSet; public class Program { public static void main(String[] args) { BitSet b = new BitSet(); // Set this bit. b.set(3); System.out.println(b.get(3)); // Flip the bit. b.flip(3); System.out.println(b.get(3)); } }true false
Bits can be set in a range. In this way we can avoid writing excess loops to set bits. Here we set the bits at indexes 2, 3 and 4 to true. We display them in a for
-loop.
import java.util.BitSet; public class Program { public static void main(String[] args) { BitSet b = new BitSet(); // Set bits in this range to true. b.set(2, 5); // Display first five bits. for (int i = 0; i < 5; i++) { System.out.println(b.get(i)); } } }false false true true true
ToByteArray
A BitSet
is composed of bytes. With toByteArray
we can access the backing store, a byte
array. Each byte
has a value determined by the bits that are set.
byte
to 1, so the first byte
equals 1. The second byte
, at position 8, also equals 1.import java.util.BitSet; public class Program { public static void main(String[] args) { BitSet b = new BitSet(); // Set bit 0 and bit 8 to true. b.set(0); b.set(8); // Convert to byte array. for (byte value : b.toByteArray()) { System.out.println(value); } } }1 1
With get, we usually access a single bit. But we can get a range of bits, like a substring, as a completely new BitSet
instance. Note how the positions of the set bits change.
import java.util.BitSet; public class Program { public static void main(String[] args) { BitSet b = new BitSet(); b.set(3); b.set(5); // Get range of bits from original set. BitSet b2 = b.get(3, 6); // Display first five bits. for (int i = 0; i < 5; i++) { System.out.println(b2.get(i)); } } }true false true false false
This method sets a bit to zero. It is the same thing as passing a false value as the second argument to the set method. We also can clear a range of bits.
clear()
will erase all bits in the BitSet
. This is similar to creating an entirely new instance.import java.util.BitSet; public class Program { public static void main(String[] args) { BitSet b = new BitSet(); // Set first four bits to true. b.set(0, 4); // Clear first two bits. b.clear(0, 2); // Display first four bits. System.out.println(b.get(0)); System.out.println(b.get(1)); System.out.println(b.get(2)); System.out.println(b.get(3)); } }false false true true
With less memory usage, programs often are faster too. BitSet
introduces some complexity, but is simpler than directly manipulating bits.