一、核心概念与功能对比
方法 |
功能 |
输入 |
输出 |
典型应用场景 |
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);