如何将int数组转换为十六进制字符串
How to convert int array to hex string
我想将 int
数组转换为十六进制字符串。我不确定我这样做是否正确。
我在另一个 class 中创建了一个 int[]
并通过 通过 msg.obj
获取它。我得到了一些十六进制值,但不确定它们是否正确。
int[] readBuf = (int[]) msg.obj; //int array is in another class
StringBuffer output=new StringBuffer();
for (int a:readBuf) {
int val1 = a & 0xff;
output.append(Integer.toHexString(val1));
}
dataView.setText(output);
假设我理解你的意图,代码有两个问题:
int val1 = a & 0xff;
您只使用了 int 的最后一个字节。如果要转换整个整数,请删除 &0xff
.
你要确保 Integer.toHexString
的输出总是在前面用零填充,所以它的长度总是 8 个字符(因为 4 字节 long int 的每个字节都需要 2人物)。否则数组 {1,2,3}
和数组 {291}
都会给你相同的字符串 - 123
.
这是一个快速但粗略的工作代码示例
public static String byteToUnsignedHex(int i) {
String hex = Integer.toHexString(i);
while(hex.length() < 8){
hex = "0" + hex;
}
return hex;
}
public static String intArrToHex(int[] arr) {
StringBuilder builder = new StringBuilder(arr.length * 8);
for (int b : arr) {
builder.append(byteToUnsignedHex(b));
}
return builder.toString();
}
public static void main(String[] args){
System.out.println(intArrToHex(new int[]{1,2,3}));
System.out.println(intArrToHex(new int[]{291}));
System.out.println(intArrToHex(new int[]{0xFFFFFFFF}));
}
输出:
000000010000000200000003
00000123
ffffffff
@Malt 的回答肯定突出了您的代码的问题:它没有用 0 填充 int
十六进制值;并且您使用 a & 0xff
屏蔽 int 以仅获取最后 8 位。你最初的问题暗示你只是在每个 int
中的最后一个 byte
之后,但它真的不清楚。
你说你每秒从你的远程对象中得到结果。在具有大型阵列的慢速机器上,使用您的方法(或者更确切地说是 Malt 的更正版本)方法将长 int[]
转换为十六进制字符串可能需要大量毫秒。
一种更快的方法是使用移位从每个 int 中获取每个 4 位 nibble,并从静态十六进制查找数组中获取适当的十六进制字符(注意这确实base-16 编码,你会从 base-64 编码):
之类的东西中得到更短的字符串
public class AltConverter {
final protected static char[] encoding = "0123456789ABCDEF".toCharArray();
public String convertToString(int[] arr) {
char[] encodedChars = new char[arr.length * 4 * 2];
for (int i = 0; i < arr.length; i++) {
int v = arr[i];
int idx = i * 4 * 2;
for (int j = 0; j < 8; j++) {
encodedChars[idx + j] = encoding[(v >>> ((7-j)*4)) & 0x0F];
}
}
return new String(encodedChars);
}
}
使用 caliper (microbenchmark results here) shows this is around 11x faster † (caveat: on my machine). EDIT For anyone interested in running this and comparing the results, there is a gist here 和源代码测试此方法与您的原始方法。
即使对于单个元素数组
原始微基准使用 Caliper as I happened to be trying it out at the time. I have rewritten it to use JMH. While doing so I found that the results I linked to and copied here originally used an array that was only ever filled with 0
for each int
element. This caused the JVM to optimise the AltConverter
code for arrays with length > 1
yielding artificial 10x to 11x improvements in AltConverter
vs SimpleConverter
. JMH and Caliper produce very similar results for both the flawed and corrected benchmark. (Updated benchmark project for maven eclipse here).
这大约快 2 到 4 倍,具体取决于数组长度(在我的机器上™)。平均运行时间结果(以 ns 为单位)为:
Average run times in nanoseconds
Original method: SimpleConverter
New method: AltConverter
| N | Alt / ns | error / ns | Simple / ns | Error / ns | Speed up |
| ---------: | ---------: | ---------: | ----------: | ---------: | -------: |
| 1 | 30 | 1 | 61 | 2 | 2.0x |
| 100 | 852 | 19 | 3,724 | 99 | 4.4x |
| 1000 | 7,517 | 200 | 36,484 | 879 | 4.9x |
| 1000,0 | 82,641 | 1,416 | 360,670 | 5,728 | 4.4x |
| 1000,00 | 1,014,612 | 241,089 | 4,006,940 | 91,870 | 3.9x |
| 1000,000 | 9,929,510 | 174,006 | 41,077,214 | 1,181,322 | 4.1x |
| 1000,000,0 | 182,698,229 | 16,571,654 | 432,730,259 | 13,310,797 | 2.4x |
† 免责声明:在现实世界的应用程序中,依赖微基准测试作为性能指标是危险的,但 caliper 是一个很好的基准测试框架, jmh 恕我直言更好。 10x 4x 的性能差异,非常小的标准偏差,在 caliper 中,良好的 t 检验结果足以表明良好的性能提升,即使在更复杂的应用程序中.
我想将 int
数组转换为十六进制字符串。我不确定我这样做是否正确。
我在另一个 class 中创建了一个 int[]
并通过 通过 msg.obj
获取它。我得到了一些十六进制值,但不确定它们是否正确。
int[] readBuf = (int[]) msg.obj; //int array is in another class
StringBuffer output=new StringBuffer();
for (int a:readBuf) {
int val1 = a & 0xff;
output.append(Integer.toHexString(val1));
}
dataView.setText(output);
假设我理解你的意图,代码有两个问题:
int val1 = a & 0xff;
您只使用了 int 的最后一个字节。如果要转换整个整数,请删除&0xff
.你要确保
Integer.toHexString
的输出总是在前面用零填充,所以它的长度总是 8 个字符(因为 4 字节 long int 的每个字节都需要 2人物)。否则数组{1,2,3}
和数组{291}
都会给你相同的字符串 -123
.
这是一个快速但粗略的工作代码示例
public static String byteToUnsignedHex(int i) {
String hex = Integer.toHexString(i);
while(hex.length() < 8){
hex = "0" + hex;
}
return hex;
}
public static String intArrToHex(int[] arr) {
StringBuilder builder = new StringBuilder(arr.length * 8);
for (int b : arr) {
builder.append(byteToUnsignedHex(b));
}
return builder.toString();
}
public static void main(String[] args){
System.out.println(intArrToHex(new int[]{1,2,3}));
System.out.println(intArrToHex(new int[]{291}));
System.out.println(intArrToHex(new int[]{0xFFFFFFFF}));
}
输出:
000000010000000200000003
00000123
ffffffff
@Malt 的回答肯定突出了您的代码的问题:它没有用 0 填充 int
十六进制值;并且您使用 a & 0xff
屏蔽 int 以仅获取最后 8 位。你最初的问题暗示你只是在每个 int
中的最后一个 byte
之后,但它真的不清楚。
你说你每秒从你的远程对象中得到结果。在具有大型阵列的慢速机器上,使用您的方法(或者更确切地说是 Malt 的更正版本)方法将长 int[]
转换为十六进制字符串可能需要大量毫秒。
一种更快的方法是使用移位从每个 int 中获取每个 4 位 nibble,并从静态十六进制查找数组中获取适当的十六进制字符(注意这确实base-16 编码,你会从 base-64 编码):
之类的东西中得到更短的字符串public class AltConverter {
final protected static char[] encoding = "0123456789ABCDEF".toCharArray();
public String convertToString(int[] arr) {
char[] encodedChars = new char[arr.length * 4 * 2];
for (int i = 0; i < arr.length; i++) {
int v = arr[i];
int idx = i * 4 * 2;
for (int j = 0; j < 8; j++) {
encodedChars[idx + j] = encoding[(v >>> ((7-j)*4)) & 0x0F];
}
}
return new String(encodedChars);
}
}
使用 caliper (microbenchmark results here) shows this is around 11x faster † (caveat: on my machine). EDIT For anyone interested in running this and comparing the results, there is a gist here 和源代码测试此方法与您的原始方法。
即使对于单个元素数组
原始微基准使用 Caliper as I happened to be trying it out at the time. I have rewritten it to use JMH. While doing so I found that the results I linked to and copied here originally used an array that was only ever filled with 0
for each int
element. This caused the JVM to optimise the AltConverter
code for arrays with length > 1
yielding artificial 10x to 11x improvements in AltConverter
vs SimpleConverter
. JMH and Caliper produce very similar results for both the flawed and corrected benchmark. (Updated benchmark project for maven eclipse here).
这大约快 2 到 4 倍,具体取决于数组长度(在我的机器上™)。平均运行时间结果(以 ns 为单位)为:
Average run times in nanoseconds Original method: SimpleConverter New method: AltConverter | N | Alt / ns | error / ns | Simple / ns | Error / ns | Speed up | | ---------: | ---------: | ---------: | ----------: | ---------: | -------: | | 1 | 30 | 1 | 61 | 2 | 2.0x | | 100 | 852 | 19 | 3,724 | 99 | 4.4x | | 1000 | 7,517 | 200 | 36,484 | 879 | 4.9x | | 1000,0 | 82,641 | 1,416 | 360,670 | 5,728 | 4.4x | | 1000,00 | 1,014,612 | 241,089 | 4,006,940 | 91,870 | 3.9x | | 1000,000 | 9,929,510 | 174,006 | 41,077,214 | 1,181,322 | 4.1x | | 1000,000,0 | 182,698,229 | 16,571,654 | 432,730,259 | 13,310,797 | 2.4x |
† 免责声明:在现实世界的应用程序中,依赖微基准测试作为性能指标是危险的,但 caliper 是一个很好的基准测试框架, jmh 恕我直言更好。 10x 4x 的性能差异,非常小的标准偏差,在 caliper 中,良好的 t 检验结果足以表明良好的性能提升,即使在更复杂的应用程序中.