【问题标题】:how to improve this java code - converting byte array to int如何改进此 java 代码 - 将字节数组转换为 int
【发布时间】:2016-10-28 18:50:21
【问题描述】:

我从 BLE 设备以字节数组(小端序)的形式返回数据,并且能够让它在下面的代码中运行。但是我很好奇有没有办法以更干净的方式编写这段代码:

int val = (Integer.parseInt(String.format("%02x", data[3]), 16) << 24) |    
          (Integer.parseInt(String.format("%02x", data[2]), 16) << 16 ) |
          (Integer.parseInt(String.format("%02x", data[1]), 16) << 8) | 
          (Integer.parseInt(String.format("%02x", data[0]), 16)) << 0;

这里返回的数据打印为十六进制:

data[0] = 0
data[1] = 0
data[2] = 8
data[3] = 9f

最终的 int 值应该是 2207。

【问题讨论】:

    标签: java byte endianness


    【解决方案1】:

    假设您的字节数组包含的不仅仅是 4 个字节并且包含打包的二进制数据,那么使用专为此类事情设计的 ByteBuffer 是有意义的。

    ByteBuffer buf = ByteBuffer.wrap(data)
    buf.order(ByteOrder.LITTLE_ENDIAN);
    int val = buf.getInt(); // read 4 bytes
    int val2 = but.getShort(); // read 2
    // ... more reads
    

    如果包装缓冲区没有离开本地范围,那么逃逸分析就可以启动并基本上使其成为免费的抽象。

    【讨论】:

      【解决方案2】:

      格式化为十六进制字符串然后将其解析为整数是不必要且低效的。这相当于您的代码:

      int val = Byte.toUnsignedInt(data[3]) << 24 |
              Byte.toUnsignedInt(data[2]) << 16 |
              Byte.toUnsignedInt(data[1]) << 8 |
              Byte.toUnsignedInt(data[0]);
      

      转换为整数是必要的,因为 Java 中的字节是有符号的, 例如0x9f 是-97,如果简单地转换为int,因为它在使用&lt;&lt; 运算符时会自动发生,将变为11111111111111111111111110011111,而不是您实际需要的10011111

      为避免重复,可以使用循环,例如:

      int val = 0;
      for (int i = data.length - 1; i >= 0; i--) {
          val <<= 8;
          val |= Byte.toUnsignedInt(data[i]);
      }
      

      注意这一点,如果 data 的值颠倒了,您的原始代码会给出 2207,而不是您在问题中写的:

      byte[] data = new byte[]{(byte) 0x9f, 8, 0, 0};
      

      【讨论】:

        【解决方案3】:
        int val = 0;
        for (int i=0; i<4; i++)
        {
          val |= Integer.parseInt(String.format("%02x", data[i]), 16) << (i*8);
        }
        

        或者只是

        int val = 0;
        for (int i=0; i<4; i++)
        {
          val |= data[i] << (i*8);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-06-20
          • 1970-01-01
          • 2017-08-22
          • 2017-09-24
          • 2011-09-04
          • 1970-01-01
          相关资源
          最近更新 更多