【问题标题】:Java Iterate Bits in Byte ArrayJava 迭代字节数组中的位
【发布时间】:2021-12-21 06:44:09
【问题描述】:

如何迭代字节数组中的位?

【问题讨论】:

  • 你不能。至少不是直接的。你想做什么,也许有更好的方法。字节数组包含字节的集合。
  • 再一次,我希望 java.util.BitSet 有一个 byte[] 构造函数。
  • 可以的。我会投票给你 Jon Skeet 的方法。然而,在大多数情况下,当使用位时,有一些花哨的位运算符可以让您的任务执行得更快。如果您确切地告诉我们您要做什么,我们可能会帮助您找到比迭代位更好的方法。
  • 我正在尝试解释 bittorrent 协议的位域消息,每个位代表一个片段的可用性。我需要迭代并确定哪个对等方有哪些可用的部分。

标签: java arrays byte bit loops


【解决方案1】:

或者,您可以为此使用BitSet

byte[] bytes=...;
BitSet bitSet=BitSet.valueOf(bytes);
for(int i=0;i<bitSet.length();i++){
    boolean bit=bitSet.get(i);
    //use your bit
} 

【讨论】:

    【解决方案2】:
    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);
        }
    }
    

    【讨论】:

      【解决方案3】:

      原文:

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

      或使用 Java 习语

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

      【讨论】:

      • 如果我不得不猜测的话,我会说 C#。
      • @Oscar:这是一个左移运算符。 Java 也有。
      【解决方案4】:

      我知道,这可能不是“最酷”的方法,但您可以使用以下代码提取每一位。

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

      10011100

      位号 1 = 1

      位号 2 = 0

      位号 3 = 0

      位号 4 = 1

      位号 5 = 1

      位号 6 = 1

      位号 7 = 0

      位号 8 = 0

      【讨论】:

      • 这很酷,因为它没有使用那些“可怕”的按位运算。
      • 我认为没有必要将按位运算符用于像 OP 要求的那样简单的事情:遍历位。
      • 如果它展示了如何从 byte 数组(而不是 String 或 char 数组)中提取位,这将更好地回答这个问题
      【解决方案5】:

      另一种方法是使用像您可以找到 here 的 BitInputStream 并编写如下代码:

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

      (注意:为简洁起见,代码不包含 EOFException 或 IOException 处理。)

      但我会选择 Jon Skeets 的变体并自己做。

      【讨论】:

        【解决方案6】:

        我需要在我的应用程序中添加一些流。 Here 你可以找到我的 BitArray 实现。它不是真正的迭代器模式,但您可以以流式方式从数组中请求 1-32 位。文件后面还有一个称为 BitReader 的替代实现。

        【讨论】:

          【解决方案7】:

          您可以遍历字节数组,并为每个字节使用位运算符来遍历其位。

          【讨论】:

            【解决方案8】:

            您必须编写自己的 Iterable&lt;Boolean&gt; 实现,该实现采用字节数组,然后创建 Iterator&lt;Boolean&gt; 值,将当前索引记住到字节数组中当前索引当前字节内。然后像这样的实用方法会派上用场:

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

            (其中bit 的范围从 0 到 7)。每次调用 next() 时,您都必须在当前字节内增加位索引,如果达到“第 9 位”,则在字节数组中增加字节索引。

            这不是真的困难 - 但有点痛苦。如果您需要示例实现,请告诉我...

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-03-31
              • 1970-01-01
              • 1970-01-01
              • 2013-11-10
              • 1970-01-01
              • 1970-01-01
              • 2019-03-14
              相关资源
              最近更新 更多