在Java中将一个字节转换为长度为4的布尔数组

8

我需要将Java中的一个字节转换为由4个布尔值组成的数组。我该如何实现呢?


12
你如何想象这个转换过程会发生?一个字节包含八个比特。你想使用四个并丢弃四个吗? - Michael Petrotta
一个字节有八个比特。因此,除非保证字节值小于b1111,否则无法执行此操作。这个假设合理吗? - Catchwa
3
如果您知道感兴趣的位,这个答案几乎可以提供您所需的一切。它能够迭代字节数组中的位。 - Michael Petrotta
3个回答

13

根据Michael Petrotta在您问题的评论中的建议,您需要决定在8位字节中应测试哪些位以获得结果布尔数组。为了演示目的,假设您想要测试最右侧的四个位,那么可以尝试以下代码:

public static boolean[] booleanArrayFromByte(byte x) {
    boolean bs[] = new boolean[4];
    bs[0] = ((x & 0x01) != 0);
    bs[1] = ((x & 0x02) != 0);
    bs[2] = ((x & 0x04) != 0);
    bs[3] = ((x & 0x08) != 0);
    return bs;
}

这个例子中的十六进制值(0x010x02等)是特殊的位掩码,在所需位置只设置一个位;因此,0x01仅设置了最右边的位,0x08仅设置了从右边数第四个位。通过使用按位与运算符(&)将给定的字节与这些值进行比较,如果该位设置,则会返回该值,否则返回零。如果您想检查不同于最右侧四个的位,则必须创建不同的位掩码。


5

关于规范

其他人提出了一个非常有价值的观点:在Java中,Byte.SIZE == 8。也就是说,一个byte有8个位。你需要定义如何将8位映射为4个boolean值;否则我们只能猜测你试图做什么。


关于BitSet

无论你如何进行这种映射,boolean[]都不太可能是最好的表示方式。一个java.util.BitSet可能更好。以下是一个示例:

import java.util.*;
public class BitSetExample {
    static BitSet toBitSet(byte b) {
        BitSet bs = new BitSet(Byte.SIZE);
        for (int i = 0; i < Byte.SIZE; i++) {
            if (((b >> i) & 1) == 1) {
                bs.set(i);
            }
        }
        return bs;
    }
    public static void main(String[] args) {
        BitSet bs = toBitSet((byte) 10);
        System.out.println(bs); // prints "{1, 3}"
        System.out.println(bs.get(3)); // prints "true"
        System.out.println(bs.get(2)); // prints "false"

        byte b = 25;
        System.out.println(toBitSet(b)); // prints "{0, 3, 4}"

        bs.or(toBitSet(b));
        System.out.println(bs); // prints "{0, 1, 3, 4}"
    }
}

以上代码使用标准的位探测技术将 byte 转换为 BitSet。请注意,(byte) 10 的位 1 和位 3 是设置的(即 10 = 2^1 + 2^3,其中 ^ 表示乘方)。
该示例还展示了如何对 BitSet 进行或/集合联合操作。
关于 EnumSet 可能另一个适用的数据结构是 EnumSet,它是高度针对 enum 进行优化的 Set 实现。以下是一个示例:
import java.util.*;
public class EnumSetExample {
    enum Style {
        BOLD, ITALIC, UNDERLINE, BLINKING;
    }
    public static void main(String[] args) {
        EnumSet<Style> myStyle = EnumSet.of(Style.BOLD, Style.UNDERLINE);

        System.out.println(myStyle);
        // prints "[BOLD, UNDERLINE]"

        System.out.println(myStyle.contains(Style.UNDERLINE));
        // prints "true"
        System.out.println(myStyle.contains(Style.BLINKING));
        // prints "false" (thank goodness!)

        myStyle.add(Style.ITALIC);
        System.out.println(myStyle);
        // prints "[BOLD, ITALIC, UNDERLINE]"
    }
}

参见

  • 《Effective Java 第二版》,条款 32:使用 EnumSet 替代位域(bit fields)

0
作为maerics答案的补充,如果需要,以下是将bool数组转换回字节的方法:
public static byte byteFromBooleanArray(bool[] _boolArray)
    {
        byte x = 0;
        x += _boolArray[0] ? (byte)1 : (byte)0;
        x += _boolArray[1] ? (byte)2 : (byte)0;
        x += _boolArray[2] ? (byte)4 : (byte)0;
        x += _boolArray[3] ? (byte)8 : (byte)0;

        return x;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接