将按小端序排列的字节数组值转换为短整型数值

25

我有一个字节数组,其中数组中的数据实际上是短整型数据。这些字节按小端序排列:

3, 1, -48, 0, -15, 0, 36, 1

将其转换为short值后得到:

259, 208, 241, 292

在Java中是否有简单的方法将字节值转换为相应的short值?我可以编写一个循环,只需取出每个高字节并将其左移8位并与其低字节进行OR运算,但这会影响性能。


2
你提供了8个字节,然后是4个长整型...而8个字节只应该产生一个单一的长整型值。此外,你没有说明你的期望结果。基本上,你的问题目前非常不清楚... - Jon Skeet
1
不,这并不含糊。你有来自字节数组的数据以及它转换后的结果。再明显不过了。 - Johann
9
可以的。因为它听起来好像你实际上是在转换成“short”,而不是“long”……而且你也没有说明你期望的结果是什么。请随意不要让问题更清晰——但请记住,你是在寻求帮助,问题描述得越好,获得的帮助就越好。 - Jon Skeet
4
@AndroidDev请仔细再次阅读Jon的留言。他确实知道自己在说什么。 - andr
3
@AndroidDev:让我们看看到底不清楚什么:1)为什么你期望从8个“byte”值中得到4个“long”值,因为一个“long”有8个字节的数据;2)你正在使用什么代码来获取不正确的值;3)你希望如何处理负数;4)为什么你对试图帮助你的人很无礼。 - Jon Skeet
2个回答

58

使用java.nio.ByteBuffer,你可以指定所需的字节序:通过order()方法。

ByteBuffer提供了将数据以byte、char、getShort()getInt()、long、double等形式提取的方法。

以下是一个使用示例:

ByteBuffer bb = ByteBuffer.wrap(byteArray);
bb.order( ByteOrder.LITTLE_ENDIAN);
while( bb.hasRemaining()) {
   short v = bb.getShort();
   /* Do something with v... */
}

1
请不要期望getLong()按照问题中的示例数据将两个字节转换。你需要调用getShort()来完成这个任务。 - Jon Skeet
3
你意识到这个操作在底层实际上正在执行你声称会有性能损失(可能是不可接受的)的位运算或,对吗? - Jon Skeet
如果不查看Java内部编码,它是如何在“引擎盖下”运行的并不明显。尽管如此,任何本地调用通常比您在更高级别上尝试复制的任何内容具有更高的性能。 - Johann
2
@AndroidDev:它们不是本地的。它们是用Java编写的,而Hotspot将以我所知道的方式JIT您自己的代码。查看ByteBuffer、HeapByteBuffer和Bits,按照代码路径很容易。实际上,考虑到间接层次,我怀疑如果您手动编写代码,它会比使用ByteBuffer更快。在假定性能损失显著之前,您是否进行了测试? - Jon Skeet
3
您说得对。上面的代码比仅使用移位和或操作字节慢大约6倍。这让我感到相当惊讶。 - Johann
显示剩余3条评论

2
 /* Try this: */
public static short byteArrayToShortLE(final byte[] b, final int offset) 
{
        short value = 0;
        for (int i = 0; i < 2; i++) 
        {
            value |= (b[i + offset] & 0x000000FF) << (i * 8);
        }            

        return value;
 }

 /* if you prefer... */
 public static int byteArrayToIntLE(final byte[] b, final int offset) 
 {
        int value = 0;

        for (int i = 0; i < 4; i++) 
        {
           value |= ((int)b[i + offset] & 0x000000FF) << (i * 8);
        }

       return value;
 }

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