1. 方法定义
public int hashCode()
- 返回值:字符的 Unicode 值(
int
类型) - 所属类:
java.lang.Character
- 等价实现:
(int) charValue
2. 功能说明
- 返回
Character
对象表示的字符的 Unicode 码点值 - 实现原理:
public int hashCode() { return (int) value; // value 是 Character 内部的 char 字段 }
- 符合
hashCode()
通用约定:- 相同字符返回相同哈希码
- 不同字符返回不同哈希码(因为 Unicode 唯一)
3. 示例代码
public class CharacterHashCodeExample {
public static void main(String[] args) {
// 基本字符
System.out.println("'A' 的哈希码: " + new Character('A').hashCode()); // 65
System.out.println("'a' 的哈希码: " + new Character('a').hashCode()); // 97
System.out.println("'0' 的哈希码: " + new Character('0').hashCode()); // 48
// 特殊字符
System.out.println("空格哈希码: " + new Character(' ').hashCode()); // 32
System.out.println("换行符哈希码: " + new Character('\n').hashCode()); // 10
// Unicode扩展字符
char heart = '❤'; // U+2764
System.out.println("'❤' 的哈希码: " + new Character(heart).hashCode()); // 10084
// 在HashMap中使用
Map<Character, String> charMap = new HashMap<>();
charMap.put('★', "五角星");
System.out.println(charMap.get('★')); // 输出 "五角星"
}
}
4. 操作步骤(详细指南)
步骤1:创建 Character 对象
// 方式1:构造函数(Java 9+ 已标记为过时)
Character ch1 = new Character('A');
// 方式2:自动装箱(推荐)
Character ch2 = 'B';
// 方式3:valueOf()(最优)
Character ch3 = Character.valueOf('C');
步骤2:调用 hashCode()
int hash1 = ch1.hashCode(); // 返回 65
int hash2 = ch2.hashCode(); // 返回 66
步骤3:直接使用 char 值(避免对象创建)
char c = 'D';
int hash = (int) c; // 等价于 hashCode(),返回 68
步骤4:在自定义类中集成
public class User {
private Character gender; // 'M'/'F'
@Override
public int hashCode() {
int result = 17;
result = 31 * result + (gender != null ? gender.hashCode() : 0);
return result;
}
}
5. 常见错误
空指针异常
Character ch = null; int hash = ch.hashCode(); // NullPointerException
混淆大小写字符
Character a = 'a'; Character A = 'A'; a.hashCode() == A.hashCode(); // 97 != 65 → false
代理对处理错误
// 错误:拆解代理对 char high = '\uD83D'; // 高位代理 char low = '\uDE00'; // 低位代理 int hash1 = new Character(high).hashCode(); // 55357 int hash2 = new Character(low).hashCode(); // 56832 // 正确:使用codePoint处理代理对 String emoji = "😀"; int fullCode = emoji.codePointAt(0); // 128512
6. 注意事项
Unicode 范围:
- 基本多文种平面(BMP):U+0000 到 U+FFFF
- 辅助平面:U+10000 到 U+10FFFF(需代理对)
代理对处理:
// BMP字符(直接处理) char euro = '€'; // U+20AC int euroHash = euro; // 8364 // 辅助平面字符(需特殊处理) String rocket = "🚀"; // U+1F680 int rocketCode = rocket.codePointAt(0); // 128640
不可变性:
Character ch = 'X'; ch.hashCode(); // 88 ch = 'Y'; // 创建新对象 ch.hashCode(); // 89
7. 最佳实践与性能优化
避免包装类型创建
// 反例:创建多余对象 for (char c : text.toCharArray()) { int hash = new Character(c).hashCode(); // 每次循环创建对象 } // 正例:直接转换 for (char c : text.toCharArray()) { int hash = (int) c; // 无对象创建 }
批量处理优化
// 高效计算字符串哈希 public int stringHash(String s) { int hash = 0; for (int i = 0; i < s.length(); i++) { hash = 31 * hash + s.charAt(i); // 直接使用char值 } return hash; }
代理对安全处理
// 正确处理所有Unicode字符 public int safeHash(CharSequence seq) { int hash = 0; for (int i = 0; i < seq.length(); ) { int codePoint = Character.codePointAt(seq, i); hash = 31 * hash + codePoint; i += Character.charCount(codePoint); } return hash; }
内存敏感场景优化
// 替代Map<Character, Value> public class CharMap<V> { private Object[] table = new Object[65536]; // 直接索引 public void put(char key, V value) { table[key] = value; // 直接使用char值作为索引 } }
总结对比表
特性 | Character.hashCode() | 直接 (int) char |
---|---|---|
功能 | 返回包装对象的哈希码 | 相同功能 |
对象创建 | 需要 Character 实例 | 无对象创建 |
空指针风险 | 可能(需判空) | 无(原始类型) |
代理对支持 | 不支持(仅返回单个char值) | 同左 |
性能开销 | 轻微(JIT可优化) | 零开销 |
适用场景 | 已存在Character对象时 | 原始char操作时 |