La Classe BitSet in Java

Concetti Chiave
  • La classe BitSet gestisce un array di bit dinamico, consentendo operazioni bitwise come AND, OR e XOR.
  • I bit possono essere impostati, azzerati e invertiti, e la classe fornisce metodi per ottenere il numero di bit impostati e la loro posizione.
  • La classe implementa metodi per operazioni di confronto e manipolazione dei bit, come and(), or(), xor(), e flip().
  • I bit possono essere convertiti in array di byte o long, e viceversa.
  • La classe è utile per gestire set di bit, come in applicazioni di crittografia, compressione dei dati e gestione di flag.

La Classe BitSet

Una classe BitSet crea un tipo speciale di array che contiene valori di bit sotto forma di valori boolean. Questo array può aumentare di dimensione secondo necessità. Questo lo rende simile a un vettore di bit.

I costruttori di BitSet sono mostrati qui:

BitSet()
BitSet(int dimensione)

La prima versione crea un oggetto predefinito. La seconda versione consente di specificare la sua dimensione iniziale (cioè, il numero di bit che può contenere). Tutti i bit sono inizializzati a false.

BitSet definisce i metodi elencati nella tabella seguente:

Metodo Descrizione
void and(BitSet insiemeBit) Esegue l'AND dei contenuti dell'oggetto BitSet invocante con quelli specificati da insiemeBit. Il risultato è posto nell'oggetto invocante.
void andNot(BitSet insiemeBit) Per ogni bit impostato in insiemeBit, il bit corrispondente nel BitSet invocante viene azzerato.
int cardinality() Restituisce il numero di bit impostati nell'oggetto invocante.
void clear() Azzera tutti i bit.
void clear(int indice) Azzera il bit specificato da indice.
void clear(int indiceInizio, int indiceFine) Azzera i bit da indiceInizio a indiceFine–1.
Object clone() Duplica l'oggetto BitSet invocante.
boolean equals(Object insiemeBit) Restituisce true se l'insieme di bit invocante è equivalente a quello passato in insiemeBit. Altrimenti, il metodo restituisce false.
void flip(int indice) Inverte il bit specificato da indice.
void flip(int indiceInizio, int indiceFine) Inverte i bit da indiceInizio a indiceFine–1.
boolean get(int indice) Restituisce lo stato corrente del bit all'indice specificato.
BitSet get(int indiceInizio, int indiceFine) Restituisce un BitSet che consiste dei bit da indiceInizio a indiceFine–1. L'oggetto invocante non viene modificato.
int hashCode() Restituisce il codice hash per l'oggetto invocante.
boolean intersects(BitSet insiemeBit) Restituisce true se almeno una coppia di bit corrispondenti all'interno dell'oggetto invocante e insiemeBit sono impostati.
boolean isEmpty() Restituisce true se tutti i bit nell'oggetto invocante sono azzerati.
int length() Restituisce il numero di bit richiesti per contenere i contenuti del BitSet invocante. Questo valore è determinato dalla posizione dell'ultimo bit impostato.
int nextClearBit(int indiceInizio) Restituisce l'indice del prossimo bit azzerato (cioè, il prossimo bit false), partendo dall'indice specificato da indiceInizio.
int nextSetBit(int indiceInizio) Restituisce l'indice del prossimo bit impostato (cioè, il prossimo bit true), partendo dall'indice specificato da indiceInizio. Se nessun bit è impostato, viene restituito –1.
void or(BitSet insiemeBit) Esegue l'OR dei contenuti dell'oggetto BitSet invocante con quello specificato da insiemeBit. Il risultato è posto nell'oggetto invocante.
int previousClearBit(int indiceInizio) Restituisce l'indice del prossimo bit azzerato (cioè, il prossimo bit false) a o prima dell'indice specificato da indiceInizio. Se nessun bit azzerato viene trovato, viene restituito –1.
int previousSetBit(int indiceInizio) Restituisce l'indice del prossimo bit impostato (cioè, il prossimo bit true) a o prima dell'indice specificato da indiceInizio. Se nessun bit impostato viene trovato, viene restituito –1.
void set(int indice) Imposta il bit specificato da indice.
void set(int indice, boolean v) Imposta il bit specificato da indice al valore passato in v. true imposta il bit; false azzera il bit.
void set(int indiceInizio, int indiceFine) Imposta i bit da indiceInizio a indiceFine–1.
void set(int indiceInizio, int indiceFine, boolean v) Imposta i bit da indiceInizio a indiceFine–1 al valore passato in v. true imposta i bit; false azzera i bit.
int size() Restituisce il numero di bit nell'oggetto BitSet invocante.
IntStream stream() Restituisce uno stream che contiene le posizioni dei bit, dal basso all'alto, che hanno bit impostati.
byte[] toByteArray() Restituisce un array di byte che contiene l'oggetto BitSet invocante.
long[] toLongArray() Restituisce un array di long che contiene l'oggetto BitSet invocante.
String toString() Restituisce l'equivalente stringa dell'oggetto BitSet invocante.
static BitSet valueOf(byte[] v) Restituisce un BitSet che contiene i bit in v.
static BitSet valueOf(ByteBuffer v) Restituisce un BitSet che contiene i bit in v.
static BitSet valueOf(long[] v) Restituisce un BitSet che contiene i bit in v.
static BitSet valueOf(LongBuffer v) Restituisce un BitSet che contiene i bit in v.
void xor(BitSet insiemeBit) Esegue lo XOR dei contenuti dell'oggetto BitSet invocante con quello specificato da insiemeBit. Il risultato è posto nell'oggetto invocante.
Tabella 1: Metodi della classe BitSet.

Vediamo un esempio che mostra come utilizzare BitSet. Questo programma crea due oggetti BitSet e imposta alcuni bit in ciascuno di essi. Quindi, esegue operazioni AND, OR e XOR sui due oggetti BitSet e stampa i risultati.

// Dimostrazione BitSet.
import java.util.BitSet;

class DimostrazioneBitSet {

    public static void main(String[] args) {

        // Crea due BitSet di dimensione 16
        BitSet bit1 = new BitSet(16);
        BitSet bit2 = new BitSet(16);

        // Imposta alcuni bit in bit1 e bit2
        // bit1 ha i bit 0, 2, 4, 6, 8, 10, 12 e 14 impostati
        // bit2 ha i bit 1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13
        // e 14 impostati
        // (cioè, i bit 0, 5, 10 e 15 sono azzerati)
        for(int i=0; i<16; i++) {
            if((i%2) == 0) bit1.set(i);
            if((i%5) != 0) bit2.set(i);
        }

        System.out.println("Pattern iniziale in bit1: ");
        System.out.println(bit1);
        System.out.println("\nPattern iniziale in bit2: ");
        System.out.println(bit2);

        // Effettua l'AND dei bit
        // bit2 con bit1 e stampa il risultato
        // bit2 contiene i bit 2, 4, 6, 8, 12 e 14
        // che sono anche impostati in bit1
        bit2.and(bit1);
        System.out.println("\nbit2 AND bit1: ");
        System.out.println(bit2);

        // Effettua l'OR dei bit
        // bit2 con bit1 e stampa il risultato
        // bit2 contiene i bit 0, 2, 4, 6, 8, 10, 12 e 14
        // che sono impostati in bit1
        bit2.or(bit1);
        System.out.println("\nbit2 OR bit1: ");
        System.out.println(bit2);

        // Effettua lo XOR dei bit
        // bit2 con bit1 e stampa il risultato
        // bit2 contiene i bit 1, 3, 5, 7, 9, 11 e 13
        // che sono impostati in bit2 ma non in bit1
        // e viceversa
        bit2.xor(bit1);
        System.out.println("\nbit2 XOR bit1: ");
        System.out.println(bit2);
    }

}

L'output di questo programma è mostrato qui. Quando toString() converte un oggetto BitSet nel suo equivalente stringa, ogni bit impostato è rappresentato dalla sua posizione di bit. I bit azzerati non vengono mostrati da toString().

Pattern iniziale in bit1: 
{0, 2, 4, 6, 8, 10, 12, 14}

Pattern iniziale in bit2: 
{1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14}

bit2 AND bit1: 
{2, 4, 6, 8, 12, 14}

bit2 OR bit1: 
{0, 2, 4, 6, 8, 10, 12, 14}

bit2 XOR bit1: 
{}