什么是HashCode?

目录

一、hashCode 的核心作用

二、hashCode 与 equals 的强制规范

三、hashCode 的计算逻辑

1. 默认实现(Object 类)

2. 常见类的重写实现

四、为什么重写 equals 必须重写 hashCode?

总结


在 Java 中,hashCode() 是 Object 类定义的一个方法(所有类都间接继承自 Object),它返回一个 int 类型的哈希码值(哈希值)。这个值本质是对象的一种 “数字指纹”,由对象的内部信息(如属性值)计算得出,核心作用是辅助哈希机制(如 HashMap、HashSet)实现高效的存储和查询

一、hashCode 的核心作用

hashCode() 的设计初衷是为了快速定位对象在哈希表中的位置,减少 “对象是否存在” 的判断成本。

举个例子:在 HashSet 中判断 “是否包含某个对象” 时,若直接用 equals() 逐个比较集合中的所有对象,时间复杂度是 O(n)(效率低);而借助 hashCode() 可以先通过哈希值定位到对象可能存在的 “小范围区域”(如 HashMap 的桶),再在该区域内用 equals() 精确比较,时间复杂度可优化到 O(1)(平均)。

二、hashCode 与 equals 的强制规范

Java 语言规范对 hashCode() 和 equals() 有严格的约束,这是保证哈希集合(如 HashMap)正确工作的前提:

  1. 若两个对象 equals(Object o) 返回 true,则它们的 hashCode() 必须返回相同的值。(原因:如果两个对象 “相等”,哈希机制必须将它们视为同一个对象,否则会在哈希表中存储重复数据。)

  2. 若两个对象 hashCode() 返回相同的值,它们的 equals(Object o) 不一定返回 true。(这是哈希冲突:不同对象可能计算出相同的哈希值,此时需要用 equals() 进一步区分。)

三、hashCode 的计算逻辑

hashCode() 的具体计算方式由类自行定义(可重写),核心原则是:相同属性的对象应返回相同的哈希值,不同属性的对象应尽量返回不同的哈希值(减少冲突)

1. 默认实现(Object 类)

Object 类的 hashCode() 是 native 方法(底层由 C++ 实现),通常返回对象的内存地址的哈希映射值(不同对象的内存地址不同,因此哈希值也不同)。

2. 常见类的重写实现
  • String 类:根据字符序列计算哈希值,相同字符序列的字符串哈希值一定相同:

    java

    运行

    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;
            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i]; // 31是质数,减少哈希冲突
            }
            hash = h;
        }
        return h;
    }
    

    例:"abc".hashCode() 与 "abc".hashCode() 结果相同,"abc" 与 "abd" 结果不同。

  • 自定义类:通常根据关键属性重写 hashCode(),确保 “属性相同的对象哈希值相同”。例如:

    java

    运行

    class Student {
        private String id;
        private String name;
    
        // 仅根据id计算哈希值(id相同则视为同一学生)
        @Override
        public int hashCode() {
            return id.hashCode(); 
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return id.equals(student.id); // 与hashCode逻辑一致
        }
    }
    

四、为什么重写 equals 必须重写 hashCode?

如果只重写 equals() 而不重写 hashCode(),会违反 Java 规范的第一条(相等的对象哈希值必须相同),导致哈希集合工作异常。

例如:两个 Student 对象 s1 和 s2 的 id 相同(s1.equals(s2) = true),但未重写 hashCode() 时,它们的哈希值默认是内存地址的映射(可能不同)。此时将它们放入 HashSet 中,HashSet 会认为它们是不同对象,导致重复存储(违背 Set 不重复的特性)。

总结

hashCode() 是对象的 “数字指纹”,核心作用是辅助哈希机制快速定位对象,与 equals() 配合保证哈希集合的正确性和效率。其关键规范是:相等的对象必须有相同的哈希值,哈希值相同的对象不一定相等。在自定义类中,若重写 equals(),必须同时重写 hashCode(),且两者逻辑保持一致(基于相同的属性计算)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值