2016-10-28 15 views
1

我有一個數據從一個BLE設備以字節數組(小端)返回,並能夠使它在我們下面的這段代碼中工作。然而林好奇的是有寫這個代碼在一個清潔的方式的方式:如何改進這個java代碼 - 將字節數組轉換爲int

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

回答

0

將其格式化爲十六進制字符串並將其解析爲整數是沒有必要的和低效的。這相當於代碼:

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]); 
} 

注意這和你原來的代碼提供2207如果data的值是反轉的,而不是你在你的問題中寫道:

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); 
} 
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 

如果包裝緩衝區沒有離開本地範圍,則逃逸分析可以啓動並基本上使其成爲免費的抽象。