如何将byte[]转换为Byte[],以及反之?

96
如何在不使用任何第三方库的情况下将byte[]转换为Byte[],以及将Byte[]转换为byte[]
是否有一种使用标准库快速实现的方法?

5
十个问题,只有一个被接受?不好。 - Alfabravo
为什么你需要/有一个Byte[]?看起来不是一个好主意... 要么使用byte[]或者List<Byte> - Dunes
如果值可以为空,则可能有用,但可能不是非常高效(即浪费存储字节的所有空间优势,因为存在所有对象引用)? - DNA
但是如果你有空引用,你不能将Byte[]转换为byte[] - Dunes
@BalusC 好的,1/7。还没有太大的进展! - Alfabravo
有Byte[]的一个原因是它成为在List<Byte>上尝试调用toArray的中间形式。在这种情况下,编写自己的循环似乎是最简单的方法。 - Ben
9个回答

89
byte[] to Byte[] :
byte[] bytes = ...;
Byte[] byteObject = ArrayUtils.toObject(bytes);

将Byte[]转换为byte[]:
Byte[] byteObject = new Byte[0];
byte[] bytes = ArrayUtils.toPrimitive(byteObject);

注意:ArrayUtils不是Java的一部分,而是Apache库。

1
为什么这不是最佳答案?有性能原因还是只是回答得晚? - mvorisek
45
因为 ArrayUtils 不是 Java 的一部分,而是 Apache 库。 - mvorisek
我同意@mvorisek的观点,这应该被认为是最佳答案。只需添加org.apache.commons.lang3.ArrayUtils。 - Alex8752
1
不幸的是,ArrayUtils 不是 Java 标准包的一部分。 - Binita Bharati
Apache Commons Lang是一个非常棒的包,应该成为任何Java项目的一部分。 - Frédéric Nobre
问题明确要求不使用第三方库。 - undefined

61

Byte 类是 byte 基本类型的一种包装类。以下代码可实现此功能:

byte[] bytes = new byte[10];
Byte[] byteObjects = new Byte[bytes.length];

int i=0;    
// Associating Byte array values with bytes. (byte[] to Byte[])
for(byte b: bytes)
   byteObjects[i++] = b;  // Autoboxing.

....

int j=0;
// Unboxing Byte values. (Byte[] to byte[])
for(Byte b: byteObjects)
    bytes[j++] = b.byteValue();

4
强烈建议使用Byte.valueOf(b)而不是new Byte(b)。如果Byte类没有为每个字节缓存每个值,我会感到惊讶。 - Dunes
2
我认为最好使用Byte.valueOf(byte)。JavaDocs说,相对于构造函数Byte(byte),通常应该优先使用此方法,因为所有字节值都被缓存,所以这种方法可能会产生更好的空间和时间性能。 - Edwin Dalorzo
10
使用自动装箱,你可以简单地执行 byteObjects[i++] = b; - Code-Apprentice
5
我会使用new Byte[bytes.length];代替new Byte[10];,以使代码更加合理。 - BalusC
3
我看到你在for循环中使用了两个“计数器”:一个用于迭代原始字节数组和/或Byte对象数组,另一个用于递增原始字节数组和/或Byte对象数组的索引。对我来说,这是不好的做法。如果此代码由他人维护,并且有人将计数器“i”从0修改为其他值,或者将i ++更改为++ i,则索引将不再匹配。我并不主张任何人首先修改代码,但这是初学者常见的陷阱。我的建议是保持两个数组的索引同步。 - user504342
显示剩余2条评论

22

Java 8 解决方案:

Byte[] toObjects(byte[] bytesPrim) {
    Byte[] bytes = new Byte[bytesPrim.length];
    Arrays.setAll(bytes, n -> bytesPrim[n]);
    return bytes;
}

很遗憾,你无法通过这种方式将Byte[]转换为byte[]Arrays可以为double[]int[]long[]提供setAll,但对于其他原始类型则不行。


对我来说最好的答案是简单的代码且没有第三方库。 - Liscare

16

您可以使用Apache Commons Lang库中的ArrayUtils类中的toPrimitive方法,如此处所建议-Java - Byte[] to byte[]


这实际上是最好的答案,至少对于那些添加 commons-lang 依赖不是问题的人来说。 - ARRG

8
byte[] toPrimitives(Byte[] oBytes)
{

    byte[] bytes = new byte[oBytes.length];
    for(int i = 0; i < oBytes.length; i++){
        bytes[i] = oBytes[i];
    }
    return bytes;

}

反向:

//byte[] to Byte[]
Byte[] toObjects(byte[] bytesPrim) {

    Byte[] bytes = new Byte[bytesPrim.length];
    int i = 0;
    for (byte b : bytesPrim) bytes[i++] = b; //Autoboxing
    return bytes;

}

5

从byte[]到Byte[]:

    byte[] b = new byte[]{1,2};
    Byte[] B = new Byte[b.length];
    for (int i = 0; i < b.length; i++)
    {
        B[i] = Byte.valueOf(b[i]);
    }

从 Byte[] 到 byte[](使用我们之前定义的 B):

    byte[] b2 = new byte[B.length];
    for (int i = 0; i < B.length; i++)
    {
        b2[i] = B[i];
    }

4
如果有人喜欢使用Stream API而不是普通的循环。
private Byte[] toObjects(byte[] bytes) {
    return IntStream.range(0, bytes.length)
            .mapToObj(i -> bytes[i])
            .toArray(Byte[]::new);
}

1
反之呢? - ElectRocnic
我认为你无法从Stream中获取byte[]。Stream API具有mapToInt()、mapToDouble()和mapToLong()方法,但没有mapToByte()方法。 - mkalmo

0

退一步,看看更大的画面。你卡在了将byte[]转换为Byte[]或反之亦然,因为Java对类型大小写敏感,像这样:

List< Byte> 或 List<Byte[]>

现在你有byte[]和Byte[],需要进行转换。这会有所帮助。

将所有的byte[]都保存在一个列表中,像这样:List<byte[]>,而不是List< Byte>或List<Byte[]>。(byte是一个原始类型,byte[]是一个对象)

当你获取字节时,可以这样做(网络套接字示例):

ArrayList<byte[]> compiledMessage = new ArrayList<byte[]>;
...
compiledMessage.add(packet.getData());

然后,当您想要将所有字节放入单个消息中时,请执行以下操作:

byte[] fromListOfNotByteArray (List<byte[]> list) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos;
    try {
        oos = new ObjectOutputStream(baos);
        oos.writeObject(list);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return baos.toByteArray();
}

这样,您可以将所有部分保存在List<byte[]>中,将整个部分保存在byte[]中,而无需在for循环中进行大量疯狂的复制任务,并且到处都是小baby byte[]。 ;)

现在您知道了 - 教给其他人。


0

自从Java 8版本以后:

byte[] bytes = new bytes[byteObject.length];
IntStream.range(0, byteObject.length).forEach(x -> bytes [x] = byteObject[x]);

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