web-dev-qa-db-fra.com

BitSet de et vers entier / long

Si j'ai un entier sur lequel j'aimerais effectuer une manipulation de bits, comment puis-je le charger dans un Java.util.BitSet? Comment puis-je le reconvertir en entier ou long? Je ne suis pas tellement préoccupé par la taille du BitSet - il sera toujours de 32 ou 64 bits. Je voudrais simplement utiliser les méthodes set(), clear(), nextSetBit() et nextClearBit() plutôt que les opérateurs au niveau du bit, mais je peux ' t trouver un moyen simple d'initialiser un ensemble de bits avec un type numérique.

51
ataylor

Le code suivant crée un ensemble de bits à partir d'une valeur longue et vice versa:

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;
  }
}

EDITÉ: Maintenant, les deux directions, @leftbrain: de cause, vous avez raison

52
Arne Burmeister

Ajoutez à la réponse finnw: il y a aussi BitSet.valueOf(long[]) et BitSet.toLongArray() . Donc:

int n = 12345;
BitSet bs = BitSet.valueOf(new long[]{n});
long l = bs.toLongArray()[0];
35
GKislin

Java 7 a BitSet.valueOf(byte[]) et BitSet.toByteArray()

Si vous êtes bloqué avec Java 6 ou antérieur, vous pouvez utiliser BigInteger s'il n'est pas susceptible d'être un goulot d'étranglement des performances - il a getLowestSetBit, setBit et clearBit méthodes (les deux dernières créeront un nouveau BigInteger au lieu de modifier sur place.)

18
finnw

Pour récupérer un long d'un petitBitSet d'une manière 'streamy' :

long l = bitSet.stream()
        .takeWhile(i -> i < Long.SIZE)
        .mapToLong(i -> 1L << i)
        .reduce(0, (a, b) -> a | b);

Vice versa:

BitSet bitSet = IntStream.range(0, Long.SIZE - 1)
        .filter(i -> 0 != (l & 1L << i))
        .collect(BitSet::new, BitSet::set, BitSet::or);

N.B .: Utilisation de BitSet::valueOf et BitSet::toLongArray est bien sûr plus facile.

3
charlie

Assez directement de la documentation de nextSetBit

value=0;
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
 value += (1 << i)
 }
1
user3799584