2009-06-23 20 views
31

Come posso iterare i bit in un array di byte?Bit Iterate Java in matrice di byte

+0

Non è possibile.Almeno non direttamente. Cosa stai cercando di fare, forse c'è un modo migliore. Una matrice di byte contiene una raccolta di byte. – OscarRyz

+15

E ancora una volta, vorrei che java.util.BitSet avesse un costruttore di byte []. –

+0

Può essere fatto. Voterò che tu vada con il metodo di Jon Skeet. Tuttavia, nella maggior parte dei casi quando si lavora con bit, ci sono alcuni operatori bit a bit fantasia che possono rendere il compito andare molto più veloce. Se ci dici cosa stai cercando di fare, esattamente, potremmo aiutarti a trovare un modo migliore di iterare i bit. – StriplingWarrior

risposta

40

Dovresti scrivere una propria implementazione di Iterable<Boolean> che ha avuto una serie di byte, e poi creato Iterator<Boolean> valori che ricordavano l'indice corrente nell'array di byte e l'indice corrente all'interno del byte corrente. Poi un metodo di utilità come questo sarebbe tornare utile:

private static Boolean isBitSet(byte b, int bit) 
{ 
    return (b & (1 << bit)) != 0; 
} 

(dove bit range da 0 a 7). Ogni volta che è stato chiamato next(), dovresti incrementare il tuo indice di bit all'interno del byte corrente e incrementare l'indice di byte nell'array di byte se raggiungi "il 9 ° bit".

Non è davvero difficile - ma un po 'di dolore. Fammi sapere se desideri un'implementazione di esempio ...

0

È possibile scorrere l'array di byte e per ogni byte utilizzare gli operatori bit per bit per iterare i relativi bit.

9

originale:

for (int i = 0; i < byteArray.Length; i++) 
{ 
    byte b = byteArray[i]; 
    byte mask = 0x01; 
    for (int j = 0; j < 8; j++) 
    { 
     bool value = b & mask; 
     mask << 1; 
    } 
} 

o utilizzando Java idiomi

for (byte b : byteArray) { 
    for (int mask = 0x01; mask != 0x100; mask <<= 1) { 
     boolean value = (b & mask) != 0; 
    } 
} 
+0

@McWaffestix: è questo C++? – OscarRyz

+3

Direi C# se dovessi indovinare. –

+0

@mmyers: che dire del "<<" – OscarRyz

0

avevo bisogno di un po 'po' di streaming nella mia applicazione. Here puoi trovare la mia implementazione BitArray. Non è un vero iteratore ma puoi chiedere 1-32 bit dall'array in modo streaming. C'è anche un'implementazione alternativa chiamata BitReader più avanti nel file.

2

Un'alternativa sarebbe quella di utilizzare un BitInputStream come quella che si può trovare here e scrivere codice come questo:

BitInputStream bin = new BitInputStream(new ByteArrayInputStream(bytes)); 
    while(true){ 
     int bit = bin.readBit(); 
     // do something 
    } 
bin.close(); 

(Nota:. Codice non contiene EOFException o IOException movimentazione per brevità)

Ma io andrei con la variante di Jon Skeets e lo farei per conto mio.

2

Lo so, probabilmente non è il modo "più bello" per farlo, ma è possibile estrarre ogni bit con il seguente codice.

int n = 156; 

String bin = Integer.toBinaryString(n); 
System.out.println(bin); 

char arr[] = bin.toCharArray(); 
for(int i = 0; i < arr.length; ++i) { 
    System.out.println("Bit number " + (i + 1) + " = " + arr[i]); 
} 

numero Bit 1 = 1

numero Bit 2 = 0

numero Bit 3 = 0

numero

Bit 4 = 1

numero di bit 5 = 1

numero Bit 6 = 1

numero Bit 7 = 0

numero Bit 8 = 0

+2

È bello perché non fa uso di quelle operazioni "bituminose" spaventose. – Reginaldo

+0

Non vedo alcuna necessità di utilizzare l'operatore bit a bit per qualcosa di semplice come richiesto dall'OP: iterate attraverso i bit. – amischiefr

+3

Questo risponderebbe meglio alla domanda se mostrasse come estrarre i bit da un * byte array * (invece di String o char array) – Jonik

16
public class ByteArrayBitIterable implements Iterable<Boolean> { 
    private final byte[] array; 

    public ByteArrayBitIterable(byte[] array) { 
     this.array = array; 
    } 

    public Iterator<Boolean> iterator() { 
     return new Iterator<Boolean>() { 
      private int bitIndex = 0; 
      private int arrayIndex = 0; 

      public boolean hasNext() { 
       return (arrayIndex < array.length) && (bitIndex < 8); 
      } 

      public Boolean next() { 
       Boolean val = (array[arrayIndex] >> (7 - bitIndex) & 1) == 1; 
       bitIndex++; 
       if (bitIndex == 8) { 
        bitIndex = 0; 
        arrayIndex++; 
       } 
       return val; 
      } 

      public void remove() { 
       throw new UnsupportedOperationException(); 
      } 
     }; 
    } 

    public static void main(String[] a) { 
     ByteArrayBitIterable test = new ByteArrayBitIterable(
        new byte[]{(byte)0xAA, (byte)0xAA}); 
     for (boolean b : test) 
      System.out.println(b); 
    } 
}