【问题标题】:converting an int[] to byte[] without creating new objects将 int[] 转换为 byte[] 而不创建新对象
【发布时间】:2018-10-30 08:17:25
【问题描述】:

我在 java 中有一个 int[],我想将其转换为 byte[]。

现在通常的方法是创建一个大小为 int 数组大小 4 倍的新 byte[],并将所有 int 逐字节复制到新的字节数组中。

但是这样做的唯一原因是因为 java 的类型安全规则。 一个 int 数组已经是一个字节数组。只是 java 不允许将 int[] 转换为 byte[] 然后将其用作 byte[]。

有没有什么办法,也许使用 jni,让 int 数组看起来像 java 的字节数组?

【问题讨论】:

  • 出于好奇,你为什么需要这样做?
  • 如果这对您来说是一个关键的性能问题,那么您最好使用另一种语言。

标签: java


【解决方案1】:

没有。无法使用本机 Java 数组接口实现对象。

在我看来,您需要一个对象来包装您的 int[],并提供以字节数组方式访问它的方法。例如

public class ByteArrayWrapper {
   private int[] array;

   public int getLength() {
      return array.length * 4;
   }

   public byte get(final int index) {
      // index into the array here, find the int, and then the appropriate byte
      // via mod/div/shift type operations....
     int val = array[index / 4];
     return (byte)(val >> (8 * (index % 4)));
   }
}

(以上内容未经测试/编译等,取决于您的字节顺序要求。纯粹是说明性

【讨论】:

  • 我认为不可能定义一个呈现完整 byte[] 接口的类,包括在需要 byte[] 的地方建立索引和传递它。所以我认为 OP 很可能必须创建一个副本。
  • 马丁是正确的。此类不能用于需要传递 byte[] 的情况。
  • @pdeva - 如上所述。这就是为什么我的回答以“否”开头的原因 :-) 在 Martin 的评论之后,我确实进一步强调了这个问题。除了回答“不”之外,我不确定自己能清楚多少。
【解决方案2】:

根据您的具体要求,您也许可以使用 NIO 的 java.nio.ByteBuffer 类。将您的初始分配作为 ByteBuffer,并使用它的 getIntputInt 方法来访问 int 值。当您需要按字节访问缓冲区时,您可以使用getput 方法。 ByteBuffer 还有一个asIntBuffer 方法,它将默认的get 和put 行为更改为int 而不是byte。

如果您使用 JNI,直接分配的 ByteBuffer(在某些情况下)允许在您的 C 代码中直接访问指针。

http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html

例如,

import java.nio.ByteBuffer;
import java.nio.IntBuffer;

// …

int[] intArray = { 1, 2, 3, 4 };

ByteBuffer byteBuffer = ByteBuffer.allocate(data.length * 4);        
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(intArray);

byte[] byteArray = byteBuffer.array();

【讨论】:

    【解决方案3】:

    如果你真的必须这样做,你可以使用对 C 的外部调用来做到这一点,但我很确定它不能在语言中完成。

    我也很好奇现有代码的外观以及您期望的额外速度。

    你知道优化的规则,对吧?

    • 1) 不要优化。
    • 2) 如果您是专家,请参阅规则 1。
    • 3) 如果您是专家,编写了最清晰的代码并且有失败的时序测试,那么:
    • 3a) 编写优化版本并将未优化的代码保留为 cmets
    • 3b) 重新测试,如果您的优化代码没有通过速度测试,请恢复!
    • 3c) 准确解释您在 cmets 中以这种方式编码的原因。包括您的速度测量和对要求的参考。
    • 3d) 如果规则 3 看起来工作量太大,请参阅规则 1

    【讨论】:

    • 减号?真的吗?因为您不能使用 C 调用来映射它(通过创建指向同一内存空间的新指针并返回它?)还是因为有人不理解不优化的重要性?
    • 我猜可能是因为它跑题了?我当然喜欢阅读它本身的优点!
    • 我会赞成,但我不同意“将未优化的代码保留为 cmets”。我建议改为在您的版本控制系统中创建一个分支。
    • @finnw 重点是注释掉的版本是可读的,优化的不是(否则优化的代码没有优化,只是正确或更好)。此外,我真的不喜欢所有 cmets 的趋势都是坏的——它们不是。有些不好,但只是批量删除 cmets 并不是一个好的解决方案,教有问题的评论者如何通过 cmets 传达含义会更有效。
    • 并不是所有的 cmets 都是坏的,但是曾经是程序一部分的注释掉的代码是坏的类型之一。如果我需要参考更易读的版本,我更喜欢简短的评论,其中包含指向 wiki 上伪代码版本的链接。
    猜你喜欢
    • 2011-06-24
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    • 2020-02-03
    • 2022-06-14
    • 2010-11-08
    • 2014-05-04
    • 2014-03-05
    相关资源
    最近更新 更多