[英]how to improve this java code - converting byte array to int
我有一个数据以字节数组(little-endian)的形式从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。
假设您的字节数组包含的字节数不止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
如果包装缓冲区没有离开本地作用域,则可以进行转义分析,从而使它成为无成本的抽象。
格式化为十六进制字符串然后将其解析为整数是不必要且效率低下的。 这等效于您的代码:
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
(使用<<
运算符时会自动发生),它将变为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};
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.