java - BitSet hacia y desde entero/largo
bitset java (6)
¿No es el método public void set(int bit)
lo que estás buscando?
Si tengo un entero que me gustaría realizar la manipulación de bits, ¿cómo puedo cargarlo en un java.util.BitSet
? ¿Cómo puedo convertirlo de nuevo a int o long? No estoy tan preocupado por el tamaño del BitSet
: siempre tendrá 32 o 64 bits de longitud. Me gustaría utilizar los métodos set()
, clear()
, nextSetBit()
y nextClearBit()
lugar de los operadores bit a bit, pero no puedo encontrar una manera fácil de inicializar un bit establecido con un tipo numérico.
Agregue a finnw respuesta: también hay BitSet.valueOf(long[])
y BitSet.toLongArray()
. Asi que:
int n = 12345;
BitSet bs = BitSet.valueOf(new long[]{n});
long l = bs.toLongArray()[0];
Bastante directamente desde la documentación de nextSetBit
value=0;
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
value += (1 << i)
}
El siguiente código crea un bit establecido a partir de un valor largo y viceversa:
public class Bits {
public static BitSet convert(long value) {
BitSet bits = new BitSet();
int index = 0;
while (value != 0L) {
if (value % 2L != 0) {
bits.set(index);
}
++index;
value = value >>> 1;
}
return bits;
}
public static long convert(BitSet bits) {
long value = 0L;
for (int i = 0; i < bits.length(); ++i) {
value += bits.get(i) ? (1L << i) : 0L;
}
return value;
}
}
EDITADO: Ahora ambas direcciones, @leftbrain: de causa, tienes razón
Java 7 tiene BitSet.valueOf(byte[])
y BitSet.toByteArray()
Si tiene problemas con Java 6 o getLowestSetBit
anteriores, puede usar BigInteger
si no es probable que sea un cuello de botella de rendimiento; tiene los getLowestSetBit
, setBit
y clearBit
(los dos últimos crearán un BigInteger
nuevo en lugar de modificar in situ).
Para obtener un long
retorno de un pequeño BitSet
de una manera ''streamy'' :
long l = bitSet.stream()
.takeWhile(i -> i < Long.SIZE)
.mapToLong(i -> 1L << i)
.reduce(0, (a, b) -> a | b);
Viceversa:
BitSet bitSet = IntStream.range(0, Long.SIZE - 1)
.filter(i -> 0 != (l & 1L << i))
.collect(BitSet::new, BitSet::set, BitSet::or);
NB: El uso de BitSet::valueOf
y BitSet::toLongArray
es, por supuesto, más fácil.