[英]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.