我想将int
数组转换为十六进制字符串。我不确定我是否正确地这样做了。
我在另一个课程中创建int[]
并通过通过 msg.obj
获取。我在Hex中得到了一些值但不确定它们是否正确。
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);
答案 0 :(得分:2)
假设我理解你的意图,代码有两个问题:
int val1 = a & 0xff;
您只获取int的最后一个字节。如果要转换整个整数,请删除&0xff
。
您希望确保Integer.toHexString
的输出始终用前面的零填充,因此它的长度始终为8个字符(因为4字节长的每个字节需要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
答案 1 :(得分:1)
@ Malt的答案肯定会突出显示代码的问题:它不会填充int
十六进制值;并且您使用a & 0xff
将int屏蔽为仅使用最后8位。您的原始问题意味着您只在每个byte
的最后int
之后,但它确实不清楚。
您说您每秒都会从远程对象获得结果。在具有大型阵列的慢速计算机上,使用您的方法(或者更确切地说是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(微基准测试results here)对原始方法进行测试显示,这比†快了大约11倍(警告:在我的机器上)。 编辑对于有兴趣运行此功能并比较结果的任何人,都有gist here的源代码。
即使对于单个元素数组
原来的微基准测试使用Caliper,因为我当时正在试用它。我已将其改写为使用JMH。在这样做的过程中,我发现results I linked to并在此处复制时最初使用的数组只为每个0
元素填充了int
。这导致JVM优化长度为&gt;的数组的AltConverter
代码。 1
与AltConverter
相比,SimpleConverter
产生了10倍至11倍的人为改进。 JMH和Caliper对有缺陷和校正的基准产生非常相似的结果。 (更新了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 |
† 免责声明:微型基准测试在实际应用程序中依赖于性能指标是危险的,但是卡尺是一个很好的基准测试框架,jmh更好。性能差异 10x 4x,其中非常小的标准偏差,卡尺良好的t检验结果足以表明即使在更复杂的应用中,性能也会提高< / em>的