目标是将每对字节转换为单个无符号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个元素来说可能不值得,除非要做很多工作。)请注意,从byte
到int
的升级需要一些额外的工作来处理不需要的符号扩展。
在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]);
}
}
如果你真的对性能很挑剔,你可以添加一个单独的计数器,或者使用右移而不是除法,但这很简单。