一、核心概念与功能对比

方法 功能 输入 输出 典型应用场景
Character.digit(char ch, int radix) 将字符转换为指定进制下的数值 字符 + 进制 (2-36) 整数值 (0-35) 或 -1 解析数字字符串
Character.forDigit(int digit, int radix) 将数值转换为指定进制下的字符 数值 (0-35) + 进制 字符 或 null 生成数字字符串

二、方法定义与参数说明

1. Character.digit

public static int digit(char ch, int radix)
public static int digit(int codePoint, int radix)
  • ch/codePoint:要转换的字符
  • radix:进制基数(2-36)
  • 返回值
    • 字符在指定进制中表示的数值(0 到 radix-1)
    • 字符无效时返回 -1

2. Character.forDigit

public static char forDigit(int digit, int radix)
  • digit:要转换的数值(0 ≤ digit < radix)
  • radix:进制基数(2-36)
  • 返回值
    • 指定进制下表示该数值的字符
    • 数值无效时返回 null 字符 (\u0000)

三、详细操作步骤与示例

步骤 1:基础转换示例

// digit 示例:字符转数值
System.out.println(Character.digit('5', 10));  // 5 (十进制)
System.out.println(Character.digit('A', 16));  // 10 (十六进制)
System.out.println(Character.digit('z', 36));  // 35 (三十六进制)
System.out.println(Character.digit('G', 16));  // -1 (无效十六进制字符)

// forDigit 示例:数值转字符
System.out.println(Character.forDigit(9, 10));   // '9' (十进制)
System.out.println(Character.forDigit(15, 16));  // 'f' (十六进制)
System.out.println(Character.forDigit(35, 36));  // 'z' (三十六进制)
System.out.println(Character.forDigit(16, 16));  // '\u0000' (超出范围)

步骤 2:进制转换工具实现

public class RadixConverter {
    /**
     * 将字符串转换为指定进制的整数值
     * @param numberStr 数字字符串
     * @param radix 进制 (2-36)
     * @return 转换后的整数值
     */
    public static int stringToInt(String numberStr, int radix) {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
            throw new IllegalArgumentException("无效进制: " + radix);
        }
        
        int result = 0;
        for (int i = 0; i < numberStr.length(); i++) {
            char c = numberStr.charAt(i);
            int digit = Character.digit(c, radix);
            
            if (digit == -1) {
                throw new NumberFormatException("无效字符: " + c);
            }
            
            result = result * radix + digit;
        }
        return result;
    }

    /**
     * 将整数值转换为指定进制的字符串
     * @param number 整数值
     * @param radix 进制 (2-36)
     * @return 转换后的字符串
     */
    public static String intToString(int number, int radix) {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
            throw new IllegalArgumentException("无效进制: " + radix);
        }
        
        if (number == 0) return "0";
        
        StringBuilder sb = new StringBuilder();
        boolean negative = number < 0;
        long num = Math.abs((long) number); // 处理Integer.MIN_VALUE
        
        while (num > 0) {
            int digit = (int) (num % radix);
            char c = Character.forDigit(digit, radix);
            sb.insert(0, c);
            num /= radix;
        }
        
        if (negative) sb.insert(0, '-');
        return sb.toString();
    }
}

// 测试用例
System.out.println(stringToInt("1A", 16));    // 26
System.out.println(stringToInt("101", 2));    // 5
System.out.println(intToString(255, 16));     // "ff"
System.out.println(intToString(10, 8));       // "12"

步骤 3:Unicode 数字转换

// 处理全角数字和特殊数字字符
System.out.println(Character.digit('5', 10));   // 5 (全角数字)
System.out.println(Character.digit('〇', 10));   // 0 (中文数字)

// 转换特殊数字字符
System.out.println(Character.forDigit(5, 10));   // '5'
System.out.println(Character.forDigit(0, 10));   // '0'

四、常见错误与解决方案

1. 进制范围错误

// 错误:超出2-36范围
int value = Character.digit('A', 37); // 未检查返回值
char c = Character.forDigit(10, 40); // 返回空字符

// 正确:验证进制范围
public static int safeDigit(char ch, int radix) {
    if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
        throw new IllegalArgumentException("无效进制: " + radix);
    }
    return Character.digit(ch, radix);
}

2. 大小写敏感问题

// 十六进制:A-F 有效,a-f 有效
System.out.println(Character.digit('a', 16)); // 10
System.out.println(Character.digit('A', 16)); // 10

// 但三十六进制:z有效,Z无效!
System.out.println(Character.digit('z', 36)); // 35
System.out.println(Character.digit('Z', 36)); // -1

// 解决方案:统一转换为小写
char input = 'Z';
int digit = Character.digit(Character.toLowerCase(input), 36);

3. 负值处理错误

// 错误:直接转换负数字符串
String negative = "-12";
int val = stringToInt(negative, 10); // 抛出异常

// 增强转换方法
public static int safeStringToInt(String str, int radix) {
    if (str.startsWith("-")) {
        return -1 * stringToInt(str.substring(1), radix);
    }
    return stringToInt(str, radix);
}

五、使用技巧与最佳实践

1. 进制转换模板

public class AdvancedConverter {
    // 支持的进制范围
    public static final int MIN_RADIX = 2;
    public static final int MAX_RADIX = 36;
    
    /**
     * 安全进制转换(支持负数和错误处理)
     */
    public static NumberParseResult parseNumber(String input, int radix) {
        if (radix < MIN_RADIX || radix > MAX_RADIX) {
            return new NumberParseResult("无效进制: " + radix);
        }
        
        if (input == null || input.isEmpty()) {
            return new NumberParseResult("输入为空");
        }
        
        boolean negative = false;
        String numberStr = input;
        
        // 处理符号
        if (input.startsWith("-")) {
            negative = true;
            numberStr = input.substring(1);
        }
        
        // 转换数字部分
        long value = 0;
        for (int i = 0; i < numberStr.length(); i++) {
            char c = numberStr.charAt(i);
            int digit = Character.digit(c, radix);
            
            if (digit == -1) {
                return new NumberParseResult("无效字符: " + c);
            }
            
            // 检查溢出
            try {
                value = Math.multiplyExact(value, radix);
                value = Math.addExact(value, digit);
            } catch (ArithmeticException e) {
                return new NumberParseResult("数值溢出");
            }
        }
        
        return new NumberParseResult(negative ? -value : value);
    }
    
    static class NumberParseResult {
        final Long value;
        final String error;
        
        NumberParseResult(long value) {
            this.value = value;
            this.error = null;
        }
        
        NumberParseResult(String error) {
            this.value = null;
            this.error = error;
        }
    }
}

2. 自定义进制编码器

public class BaseNEncoder {
    private static final String DEFAULT_ALPHABET = 
        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    private final String alphabet;
    private final int radix;
    
    public BaseNEncoder(int radix) {
        this(radix, DEFAULT_ALPHABET.substring(0, radix));
    }
    
    public BaseNEncoder(int radix, String customAlphabet) {
        if (radix < 2 || radix > 36) {
            throw new IllegalArgumentException("Radix 2-36 required");
        }
        if (customAlphabet.length() != radix) {
            throw new IllegalArgumentException("字母表长度必须等于进制");
        }
        this.radix = radix;
        this.alphabet = customAlphabet;
    }
    
    public String encode(long number) {
        if (number == 0) return String.valueOf(alphabet.charAt(0));
        
        StringBuilder sb = new StringBuilder();
        boolean negative = number < 0;
        long num = Math.abs(number);
        
        while (num > 0) {
            int digit = (int) (num % radix);
            sb.insert(0, alphabet.charAt(digit));
            num /= radix;
        }
        
        if (negative) sb.insert(0, '-');
        return sb.toString();
    }
    
    public long decode(String encoded) {
        // 实现解码逻辑(类似前面的stringToInt)
    }
}

// 使用自定义字母表
BaseNEncoder base64 = new BaseNEncoder(64, 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
System.out.println(base64.encode(123456)); // "eJA"

3. 性能优化技巧

// 1. 预计算字符映射
public class FastDigitConverter {
    private static final int MAX_RADIX = 36;
    private static final int[] CHAR_TO_DIGIT = new int[256];
    
    static {
        // 初始化ASCII字符映射
        Arrays.fill(CHAR_TO_DIGIT, -1);
        for (int radix = Character.MIN_RADIX; radix <= MAX_RADIX; radix++) {
            for (int digit = 0; digit < radix; digit++) {
                char c = Character.forDigit(digit, radix);
                if (c < CHAR_TO_DIGIT.length) {
                    CHAR_TO_DIGIT[c] = digit;
                    // 添加大写字母映射
                    char upper = Character.toUpperCase(c);
                    if (upper < CHAR_TO_DIGIT.length && upper != c) {
                        CHAR_TO_DIGIT[upper] = digit;
                    }
                }
            }
        }
    }
    
    public static int fastDigit(char ch, int radix) {
        if (ch < CHAR_TO_DIGIT.length) {
            int digit = CHAR_TO_DIGIT[ch];
            if (digit >= 0 && digit < radix) {
                return digit;
            }
        }
        return Character.digit(ch, radix);
    }
}

// 2. 批量转换优化
public static int[] batchConvert(char[] chars, int radix) {
    int[] results = new int[chars.length];
    for (int i = 0; i < chars.length; i++) {
        results[i] = Character.digit(chars[i], radix);
    }
    return results;
}

六、最佳实践总结

场景 推荐方法 注意事项
解析用户输入 Character.digit + 严格错误检查 处理大小写和非法字符
生成进制字符串 Character.forDigit 注意超出范围返回 null 字符
高性能转换 预计算映射表 仅适用于有限字符集 (ASCII)
自定义编码系统 扩展 BaseNEncoder 模式 确保字母表唯一性
处理国际数字字符 直接使用 digit 方法 支持全角数字和中文数字
大数处理 使用 BigInteger 内置方法 BigInteger 支持任意进制转换

七、特殊进制应用示例

1. 二进制数据处理

// 二进制字符串转换
String binary = "110101";
int decimal = 0;
for (char c : binary.toCharArray()) {
    int bit = Character.digit(c, 2);
    decimal = (decimal << 1) | bit;
}
System.out.println(decimal); // 53

// 生成二进制字符串
int value = 53;
StringBuilder binStr = new StringBuilder();
for (int i = 7; i >= 0; i--) {
    int bit = (value >> i) & 1;
    binStr.append(Character.forDigit(bit, 2));
}
System.out.println(binStr); // 00110101

2. UUID 压缩表示

public class UuidCompressor {
    private static final int RADIX = 36;
    
    public static String compress(UUID uuid) {
        return new BigInteger(uuid.toString().replace("-", ""), 16)
               .toString(RADIX);
    }
    
    public static UUID decompress(String compressed) {
        BigInteger bigInt = new BigInteger(compressed, RADIX);
        String hex = bigInt.toString(16);
        // 补全前导零
        hex = "0".repeat(32 - hex.length()) + hex;
        return UUID.fromString(
            hex.substring(0, 8) + "-" +
            hex.substring(8, 12) + "-" +
            hex.substring(12, 16) + "-" +
            hex.substring(16, 20) + "-" +
            hex.substring(20)
        );
    }
}

// 使用示例
UUID original = UUID.randomUUID();
String compressed = UuidCompressor.compress(original);
UUID restored = UuidCompressor.decompress(compressed);

System.out.println("原始: " + original);
System.out.println("压缩: " + compressed); // 长度从36降到25
System.out.println("恢复: " + restored);