java:将bye数组byte[1000]转换为数组int[500]的最快方法



目标是将每对字节转换为单个无符号16位int。在C中,我会定义一个16位未受质疑的int指针的数组[500],并将其指向字节数组,但在java中,我不知道这样的捷径。我知道在Java中,除了char之外没有16位的数据类型,但这不是问题。我们只需要将每两个连续的两个字节复制到整数数组的单个int中。因此,整数数组包含范围从0到65535(2^16-1)的int值。

您可以使用ByteBuffer来避免移位和屏蔽,这通常是错误的。(还有有符号和无符号)

ByteBuffer bb = ByteBuffer.wrap(bytes);
bb.order(ByteOrder.BIG_ENDIAN);  // or LITTLE_ENDIAN
short[] shorts = new short[bytes.length/2];
for (int i=0; i<shorts.length; i++)
   shorts[i] = bb.getShort();

请注意,如果您真的想要一个"无符号短",那么在java中就没有这样的东西,所以您的数组必须是整数。您可以使用进行转换

for (int i=0; i<intArray.length; i++) {
   short s = bb.getShort();
   intArray[i] = s & 0xFFFF; // mask off all the high order bits
}

我认为Java中没有像C中的别名那样的好技巧。你必须手动完成:

public int[] pack(byte[] bytes) {
    int n = bytes.length >> 1;
    int[] packed = new int[n];
    for (int i = 0; i < n; ++i) {
        int i2 = i << 1;
        int b1 = bytes[i2] & 0xff;
        int b2 = bytes[i2 + 1] & 0xff;
        packed[i] = (b1 << 8) | b2;
    }
    return packed;
}

(这可能会加快一点,但对于1000个元素来说可能不值得,除非要做很多工作。)请注意,从byteint的升级需要一些额外的工作来处理不需要的符号扩展。

在Java中并没有真正的无符号16位整数类型——除了可能char,如果你觉得自己滥用了这种语言。也就是说,这是一个使用流行的Guava实用程序库的好时机:

public short[] pack(byte[] bytes) {
   short[] result = new short[bytes.length / 2];
   for (int i = 0; i < bytes.length; i += 2) {
     result[i/2] = Shorts.fromBytes(bytes[i], bytes[i+1]);
   }
}

如果你真的对性能很挑剔,你可以添加一个单独的计数器,或者使用右移而不是除法,但这很简单。

最新更新