【问题标题】:How to convert byte[] to Byte[] and the other way around?如何将 byte[] 转换为 Byte[] 和其他方式?
【发布时间】:2012-10-17 22:27:54
【问题描述】:

在不使用任何第三方库的情况下,如何将byte[] 转换为Byte[] 以及将Byte[] 转换为byte[]

有没有办法只使用标准库快速完成?

【问题讨论】:

  • 10 个问题,一个接受了吗?不好
  • 为什么需要/拥有Byte[]?似乎不是一个好主意...使用byte[]List<Byte>
  • 如果值可以为空,可能会很有用,尽管效率可能不是很高(即,由于所有对象引用,浪费了存储字节的任何空间优势)?
  • 但是如果你有空引用,你不能将 Byte[] 转换为 byte[]...
  • @BalusC 好的,第 1 个,共 7 个。没有太大改善!

标签: java arrays byte boxing


【解决方案1】:

字节[]到字节[]:

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

字节[]到字节[]:

Byte[] byteObject = new Byte[0];
byte[] bytes = ArrayUtils.toPrimitive(byteObject);

【讨论】:

  • 为什么这不是最佳答案?有任何性能原因还是稍后才回答?
  • 因为 ArrayUtils 不是 Java 的一部分,而是 Apache lib。
  • 我同意@mvorisek,这应该被认为是最好的答案。只需添加 org.apache.commons.lang3.ArrayUtils
  • 很遗憾,ArrayUtils 不是标准 Java 包的一部分。
【解决方案2】:

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();

【讨论】:

  • 绝对会推荐Byte.valueOf(b) 而不是new Byte(b)。如果 Byte 类没有缓存一个字节的每个值,我会感到惊讶。
  • 我认为使用Byte.valueOf(byte) 可能会更好。 JavaDocs 说通常应该优先使用此方法而不是构造函数 Byte(byte),因为此方法可能会产生明显更好的空间和时间性能,因为所有字节值都被缓存。
  • 使用自动装箱,你可以简单地做byteObjects[i++] = b;
  • 我会使用 new Byte[bytes.length]; 而不是 new Byte[10]; 来保持它的合理性。
  • @Juvanis aha,我看到您在 for 循环中使用了两个“计数器”:一个用于迭代原始字节数组和/或字节对象数组,另一个用于增加原始字节数组和/或字节对象数组。对我来说,这是不好的做法。如果此代码由其他人维护,并且有人将计数器“i”从 0 修改为另一个值,或者将 i++ 更改为 ++i,则索引不再匹配。我并不是主张任何人都应该首先修改代码,但这对于初学者来说是一个常见的陷阱。我的建议是让两个数组的索引保持同步。
【解决方案3】:

如果有人更喜欢 Stream API 而不是普通循环。

private Byte[] toObjects(byte[] bytes) {
    return IntStream.range(0, bytes.length)
            .mapToObj(i -> bytes[i])
            .toArray(Byte[]::new);
}

【讨论】:

  • 反之亦然?
  • 我认为您无法从 Stream 获取 byte[]。 Stream api 有 mapToInt()、mapToDouble() 和 mapToLong() 方法,但没有 mapToByte()。
【解决方案4】:
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】:

    Java 8 解决方案:

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

    很遗憾,您无法将Byte[] 转换为byte[]Arraysdouble[]int[]long[]setAll,但对其他原始类型没有。

    【讨论】:

    • 对我来说最好的答案。代码简单,没有第三方库。
    • 当它是不起作用的代码时,它如何获得支持?
    【解决方案6】:

    您可以使用 Apache Commons 语言库 ArrayUtils 类中的 toPrimitive 方法, 正如这里所建议的 - Java - Byte[] to byte[]

    【讨论】:

    • 这实际上是最好的答案,至少对于向 commons-lang 添加依赖项不是问题的人来说。
    【解决方案7】:

    从字节[]到字节[]:

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

    【讨论】:

      【解决方案8】:

      退后一步。看看更大的图景。由于 Java 的严格类型大小写类似这样,您无法将 byte[] 转换为 Byte[] 或反之亦然

      列表 或者 列表

      现在你有 byte[] 和 Byte[] 并且必须转换。这会有所帮助。

      将所有 byte[] 保存在这样的列表中:List 而不是 List 或 List。 (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[] 中,而无需在 for 循环中进行大量疯狂的复制任务,并且到处都有小婴儿 byte[]。 ;)

      现在你知道了——教别人。

      【讨论】:

        猜你喜欢
        • 2011-06-08
        • 1970-01-01
        • 2018-09-05
        • 1970-01-01
        • 2014-07-21
        • 1970-01-01
        • 2014-04-18
        • 2014-09-01
        • 2019-04-04
        相关资源
        最近更新 更多