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. 常见错误

  1. 空指针异常

    Character ch = null;
    int hash = ch.hashCode(); // NullPointerException
    
  2. 混淆大小写字符

    Character a = 'a';
    Character A = 'A';
    a.hashCode() == A.hashCode(); // 97 != 65 → false
    
  3. 代理对处理错误

    // 错误:拆解代理对
    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. 注意事项

  1. Unicode 范围

    • 基本多文种平面(BMP):U+0000 到 U+FFFF
    • 辅助平面:U+10000 到 U+10FFFF(需代理对)
  2. 代理对处理

    // BMP字符(直接处理)
    char euro = '€'; // U+20AC
    int euroHash = euro; // 8364
    
    // 辅助平面字符(需特殊处理)
    String rocket = "🚀"; // U+1F680
    int rocketCode = rocket.codePointAt(0); // 128640
    
  3. 不可变性

    Character ch = 'X';
    ch.hashCode(); // 88
    ch = 'Y';      // 创建新对象
    ch.hashCode(); // 89
    

7. 最佳实践与性能优化

  1. 避免包装类型创建

    // 反例:创建多余对象
    for (char c : text.toCharArray()) {
        int hash = new Character(c).hashCode(); // 每次循环创建对象
    }
    
    // 正例:直接转换
    for (char c : text.toCharArray()) {
        int hash = (int) c; // 无对象创建
    }
    
  2. 批量处理优化

    // 高效计算字符串哈希
    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;
    }
    
  3. 代理对安全处理

    // 正确处理所有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;
    }
    
  4. 内存敏感场景优化

    // 替代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操作时