簡體   English   中英

如何將int數組轉換為十六進制字符串

[英]How to convert int array to hex string

我想將一個int數組轉換為一個十六進制字符串。 我不確定我是否正確執行此操作。

我在另一個類中創建一個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);

假設我了解您的意圖,那么代碼有兩個問題:

  1. int val1 = a & 0xff; 您只占用int的最后一個字節。 如果要轉換整個整數,請刪除&0xff

  2. 您要確保Integer.toHexString的輸出始終在前面填充零,因此其長度始終為8個字符(因為4字節長的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十六進制值; 並且您將int掩碼為使用a & 0xff僅占用最后8位。 您最初的問題意味着您僅在每個int的最后一個byte之后,但這確實不清楚。

您說您每秒從遠程對象獲得結果。 在具有大型數組的慢速計算機上,使用您的方法(或者您的Malt的校正版本)將您的方法將長int[]轉換為十六進制字符串可能會花費大量的毫秒。

一種更快的方法是使用位移從每個int獲取每個4位半字節 ,並從靜態十六進制查找數組中獲取適當的十六進制字符( 請注意,此操作采用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);
    }
}

使用游標卡尺測試此方法與原始方法( 此處為微基准測試結果 )顯示,速度大約提高了11倍 (注意:在我的機器上)。 編輯對於有興趣運行此程序並比較結果的任何人, 此處都有源代碼的要點

即使是單個元素數組

最初的微基准測試使用的是Caliper,因為我當時正嘗試使用它。 我已將其重寫為使用JMH 這樣做時,我發現鏈接到並復制到此處的結果最初使用的數組僅對每個int元素填充0 這導致JVM針對長度大於1數組優化了AltConverter代碼,從而在AltConverterSimpleConverter獲得了10到11倍的人工改進。 對於有缺陷和經過修正的基准測試,JMH和Caliper產生的結果非常相似。 此處更新了Maven Eclipse的基准測試項目)。

根據陣列長度的不同( 在我的機器™上 ),速度大約快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的性能差異,即使在更復雜的應用程序內良好的t檢驗結果也足以表明性能得到了很好的提高

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM