8

私のAndroidプログラムには、Javaで記述された次のメソッドがあります。

このメソッドは16進数の文字列を受け取り、ASCIIで記述された同じテキストの文字列を返します。

public static String hexToString(String hex)
{
    StringBuilder sb = new StringBuilder();

    for (int count = 0; count < hex.length() - 1; count += 2)
    {
        String output = hex.substring(count, (count + 2));    //grab the hex in pairs

        int decimal = Integer.parseInt(output, 16);    //convert hex to decimal

        sb.append((char)decimal);    //convert the decimal to character
    }

    return sb.toString();
}

この方法は問題なく機能しますが、私のプログラムは非常にタイムクリティカルであり、この方法は潜在的に何万回も呼び出されています。私のプログラムの遅い部分を分析するとき、この方法は次の理由で非常に多くの時間を費やします:

Integer.parseInt(output, 16);

hex.substring(count, (count + 2));

遅いものから順に。

同じことを達成するためのより速い方法を知っている人はいますか?

4

4 に答える 4

9

反復ごとに新しい文字列を作成しないでください。パフォーマンスを向上させる1つの方法は、char配列を使用し、文字ごとに数学演算を適用することです。

public static String hexToString(String hex) {
    StringBuilder sb = new StringBuilder();
    char[] hexData = hex.toCharArray();
    for (int count = 0; count < hexData.length - 1; count += 2) {
        int firstDigit = Character.digit(hexData[count], 16);
        int lastDigit = Character.digit(hexData[count + 1], 16);
        int decimal = firstDigit * 16 + lastDigit;
        sb.append((char)decimal);
    }
    return sb.toString();
}

この方法の詳細:

また、16進文字列をペアで解析している場合は、@L7ColWintersが提案するようにルックアップテーブルを使用できます。

private static final Map<String, Character> lookupHex = new HashMap<String, Character>();

static {
    for(int i = 0; i < 256; i++) {
        String key = Integer.toHexString(i);
        Character value = (char)(Integer.parseInt(key, 16));
        lookupHex.put(key, value);
    }
}

public static String hexToString(String hex) {
    StringBuilder sb = new StringBuilder();
    for (int count = 0; count < hex.length() - 1; count += 2) {
        String output = hex.substring(count, (count + 2));
        sb.append((char)lookupHex.get(output));
    }
    return sb.toString();
}
于 2012-08-20T14:28:50.830 に答える
3

これはどうですか...

public static String hexToString(final String str) {
 return new String(new BigInteger(str, 16).toByteArray());
}
于 2012-08-20T14:24:55.393 に答える
1

もう1つの方法は、単純な計算を行うことです。

public static int hexCharToInt(char c)
{
    int result = 0;
    if(c >= 'A' && c <= 'F')
    {
        result += (c - 'A' + 10);
    }
    else if( c >= '0' && c <= '9')
    {
            result += (c - '0');
    }
        return result;
    }

public static String hexToString(String hex)
{
    StringBuilder sb = new StringBuilder();

    for (int count = 0; count < hex.length() - 1; count += 2)
    {
        char c1 = hex.charAt(count);
        char c2 = hex.charAt(count + 1);

        int decimal = hexCharToInt(c1) * 16 + hexCharToInt(c2);

        sb.append((char)decimal);    //convert the decimal to character
    }

    return sb.toString();
}

試してみて、システムで最適なソリューションを確認してください。

于 2012-08-20T14:55:00.897 に答える
1

このコードは、 Apache Commons CodecのHexクラスから取得され、少し簡略化されています。(ここで理解する必要のない範囲チェックなどを削除しました。実際には、元の実装を使用します。)

/**
 * Converts an array of characters representing hexadecimal values into an array of bytes of those same values. The
 * returned array will be half the length of the passed array, as it takes two characters to represent any given
 * byte. An exception is thrown if the passed char array has an odd number of elements.
 * 
 * @param data
 *            An array of characters containing hexadecimal digits
 * @return A byte array containing binary data decoded from the supplied char array.
 * @throws DecoderException
 *             Thrown if an odd number or illegal of characters is supplied
 */
public static byte[] decodeHex(char[] data) throws DecoderException {

    int len = data.length;

    byte[] out = new byte[len >> 1];

    // two characters form the hex value.
    for (int i = 0, j = 0; j < len; i++) {
        int f = Character.digit(data[j], 16) << 4;
        j++;
        f = f | Character.digit(data[j], 16);
        j++;
        out[i] = (byte) (f & 0xFF);
    }

    return out;
}

返されたものを使用して、byte[]後でStringオブジェクトを作成できます。

したがって、Apache Commons Codecを使用する場合、メソッドは次のようになります。

public static String hexToString(String hex) throws UnsupportedEncodingException, DecoderException {
    return new String(Hex.decodeHex(hex.toCharArray()), "US-ASCII");
  }
于 2012-08-20T16:09:41.203 に答える