BitSet
About
The BitSet
class in Java is a part of the java.util
package and provides an efficient way to work with a sequence of bits. It represents a vector of bits that grows dynamically as needed. Each bit in the BitSet
can either be true
(set) or false
(unset), making it an ideal choice for tasks such as manipulating sets of flags, managing collections of Boolean values, or performing operations on binary data.
Internally, BitSet
uses a long array to store bits, which allows it to be memory efficient, especially compared to using an array of boolean
primitives.
How BitSet
Stores Bits Internally
BitSet
Stores Bits InternallyA
BitSet
uses an array oflong
values (long[]
) to store the bits.Each
long
in Java is 64 bits wide, meaning onelong
can store the state of 64 bits (true
orfalse
values).If you need to store, say, 128 bits, a
BitSet
will use 2 longs (128 / 64 = 2
).
How boolean[]
Stores Values Internally
boolean[]
Stores Values InternallyIn a
boolean[]
, each element represents one bit of information (true
orfalse
), but due to memory alignment and storage constraints, Java does not store booleans as single bits.Instead, Java typically uses 1 byte (8 bits) to store each
boolean
value in an array, because most hardware cannot directly address individual bits.So, a
boolean[]
of size 128 will use 128 bytes (1 byte perboolean
).
Features
Dynamic Sizing: The size of a
BitSet
is not fixed and can grow automatically as bits are set or cleared.Memory Efficiency:
BitSet
is much more memory efficient than aboolean[]
array since it stores bits compactly using long integers.Bitwise Operations: It supports logical operations such as
AND
,OR
,XOR
, andAND NOT
.Index-Based Access: Bits can be accessed and manipulated using their zero-based index.
Stream and Lambda Support: Java 8 and later versions added support for streaming through
BitSet
using methods likestream()
.Automatic Growth: When setting a bit at an index that exceeds the current size, the
BitSet
automatically resizes to accommodate the new index.Default State: All bits in a
BitSet
are initiallyfalse
.Serialization: The
BitSet
class implementsSerializable
, allowing it to be serialized and deserialized.
Declaration & Functions
Declaration
To use a BitSet
, simply import it and create an instance:
import java.util.BitSet;
// Creating a BitSet with no specified size
BitSet bitSet = new BitSet();
// Creating a BitSet with an initial size (e.g., 64 bits)
BitSet bitSetWithSize = new BitSet(64);
Key Methods and Functions
Setting and Clearing Bits:
bitSet.set(int index); // Sets the bit at the specified index to true bitSet.set(int fromIndex, int toIndex); // Sets all bits in a range to true bitSet.clear(int index); // Clears the bit at the specified index bitSet.clear(int fromIndex, int toIndex); // Clears all bits in a range bitSet.clear(); // Clears all bits in the BitSet
Getting Bit Values:
boolean value = bitSet.get(int index); // Gets the value of the bit at the specified index BitSet subSet = bitSet.get(int fromIndex, int toIndex); // Gets a subset of bits as a new BitSet
Checking State:
boolean isEmpty = bitSet.isEmpty(); // Checks if all bits are false int cardinality = bitSet.cardinality(); // Returns the number of bits set to true int length = bitSet.length(); // Returns the index of the highest set bit + 1
Logical Operations:
bitSet.and(BitSet set); // Performs logical AND with another BitSet bitSet.or(BitSet set); // Performs logical OR with another BitSet bitSet.xor(BitSet set); // Performs logical XOR with another BitSet bitSet.andNot(BitSet set); // Clears all bits in the current BitSet that are set in another BitSet
Stream Support (Java 8+):
bitSet.stream().forEach(System.out::println); // Streams the indices of bits set to true
Miscellaneous:
int size = bitSet.size(); // Returns the number of bits the BitSet can hold bitSet.flip(int index); // Toggles the bit at the specified index bitSet.flip(int fromIndex, int toIndex); // Toggles all bits in a range
Usage
1. Flags and Binary Representations:
BitSet
is often used to represent flags or enable/disable states in an application.
BitSet flags = new BitSet();
flags.set(0); // Enable first flag
flags.set(2); // Enable third flag
System.out.println(flags); // Prints: {0, 2}
2. Efficient Membership Testing:
It can be used to represent sets and perform operations like intersection and union.
BitSet set1 = new BitSet();
BitSet set2 = new BitSet();
set1.set(1);
set1.set(2);
set2.set(2);
set2.set(3);
set1.and(set2);
System.out.println(set1); // Prints: {2}
3. Data Compression:
To store large numbers of Boolean values in minimal memory.
4. Prime Number Generation (Sieve of Eratosthenes):
BitSet
is used to efficiently implement algorithms for generating prime numbers.
int n = 50;
BitSet primes = new BitSet(n);
primes.set(0, n + 1);
primes.clear(0);
primes.clear(1);
for (int i = 2; i * i <= n; i++) {
if (primes.get(i)) {
for (int j = i * i; j <= n; j += i) {
primes.clear(j);
}
}
}
System.out.println(primes); // Prints: {2, 3, 5, 7, 11, ...}
5. Stream-Based Processing:
Using
BitSet
in conjunction with streams for advanced data processing.
bitSet.stream()
.mapToObj(i -> "Bit: " + i)
.forEach(System.out::println);
Last updated
Was this helpful?