2009-06-23 43 views
31

Làm thế nào tôi có thể lặp bit trong một mảng byte?Java Iterate Bits trong Byte Array

+0

Bạn không thể.Ít nhất không trực tiếp. Bạn đang cố gắng làm gì, có lẽ có một cách tốt hơn. Một mảng byte chứa một tập hợp các byte. – OscarRyz

+15

Và một lần nữa, tôi ước rằng java.util.BitSet có một hàm tạo byte []. –

+0

Nó có thể được thực hiện. Tôi sẽ bầu bạn đi với phương pháp của Jon Skeet. Tuy nhiên, trong hầu hết các trường hợp khi làm việc với bit, có một số toán tử bitwise ưa thích có thể làm cho công việc của bạn đi nhanh hơn nhiều. Nếu bạn cho chúng tôi biết những gì bạn đang cố gắng làm, chính xác, chúng tôi có thể giúp bạn tìm một cách tốt hơn so với lặp lại các bit. – StriplingWarrior

Trả lời

40

Bạn sẽ phải viết thực hiện của riêng bạn Iterable<Boolean> mà mất một mảng byte, và sau đó tạo ra Iterator<Boolean> giá trị mà nhớ đến chỉ số hiện tại vào mảng byte chỉ số hiện tại trong byte hiện tại. Sau đó, một phương pháp tiện ích như thế này sẽ có ích:

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

(trong đó bit nằm trong khoảng từ 0 đến 7). Mỗi lần next() được gọi là bạn phải tăng chỉ số bit của bạn trong byte hiện tại và tăng chỉ số byte trong mảng byte nếu bạn đạt đến "bit thứ 9".

Nó không thực sự là cứng - nhưng hơi đau. Hãy cho tôi biết nếu bạn muốn triển khai mẫu ...

0

Bạn có thể lặp qua mảng byte và mỗi byte sử dụng toán tử bitwise để lặp qua các bit của nó.

9

gốc:

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

Hoặc sử dụng Java thành ngữ

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

@McWaffestix: Đây có phải là C++ không? – OscarRyz

+3

Tôi muốn nói C# nếu tôi phải đoán. –

+0

@mmyers: Còn về "<<" – OscarRyz

0

tôi cần một số bit truyền trong ứng dụng của tôi. Here bạn có thể tìm thấy thực thi BitArray của tôi. Nó không phải là một mô hình vòng lặp thực sự nhưng bạn có thể yêu cầu 1-32 bit từ mảng theo cách trực tuyến. Ngoài ra còn có một thực hiện thay thế được gọi là BitReader sau này trong tập tin.

2

Một thay thế sẽ được sử dụng một BitInputStream như một trong những bạn có thể tìm here và viết mã như thế này:

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

(Lưu ý:. Mã không chứa EOFException hoặc IOException xử lý cho ngắn gọn)

Nhưng tôi muốn đi với biến thể Jon Skeets và tự mình làm.

2

Tôi biết, có lẽ không phải là cách "thú vị nhất" để thực hiện điều đó, nhưng bạn có thể trích xuất từng bit bằng mã sau đây.

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

số Bit 1 = 1

số Bit 2 = 0

số Bit 3 = 0

số

Bit 4 = 1

số Bit 5 = 1

số Bit 6 = 1

Bit số 7 = 0

Bit số 8 = 0

+2

Thật tuyệt vời vì nó không sử dụng những hoạt động bit "đáng sợ" đó. – Reginaldo

+0

Tôi không thấy bất kỳ nhu cầu sử dụng toán tử bitwise cho một cái gì đó đơn giản như OP được yêu cầu: lặp qua các bit. – amischiefr

+3

Điều này sẽ trả lời câu hỏi tốt hơn nếu nó cho thấy làm thế nào để trích xuất các bit từ một mảng * * * (thay vì String hoặc mảng char) – 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); 
    } 
}