请解释 Java 中 hashCode 和 equals 方法的定义及它们之间的约定关系,并说明它们与 == 操作符的区别。
考察说明
考查对 Java 对象相等性判断机制的理解,包括 equals 与 hashCode 的约定以及引用比较与值比较的区别。
回答思路
- 【回答框架 1】equals 方法用于定义对象逻辑相等的规则,默认实现为引用比较,但通常需要重写以按业务字段判断相等。hashCode 返回对象的哈希码,用于散列集合(如 HashMap、HashSet)中的桶定位,返回值为 int 类型。
- 【回答框架 2】两者存在约定:若两个对象根据 equals 相等,则它们的 hashCode 必须相等;若 hashCode 不等,则 equals 必不相等;反过来,hashCode 相等不要求 equals 相等,这允许哈希冲突。违反约定会导致基于散列的集合行为异常,例如无法正确查找对象。
- 【回答框架 3】== 操作符用于比较引用,即内存地址是否相同,适用于基本类型值比较和引用类型对象身份比较。而 equals 默认是引用比较,但可重写为值比较。三者的核心区别是:== 比较引用,equals 比较逻辑相等(需重写),hashCode 提供散列支持。
- 【关键点 1】equals 默认是 Object 的实现,相当于 ==;重写 equals 时必须遵守自反性、对称性、传递性、一致性等规则。
- 【关键点 2】重写 equals 时必须重写 hashCode,以保证 equals 相等的对象 hashCode 相同。
- 【关键点 3】== 用于基本类型值比较(如 int == int)和引用类型地址比较;equals 用于逻辑相等判断。
- 【关键点 4】在 HashMap 等集合中,先比较 hashCode 定位桶,再通过 equals 精确比较,hashCode 不均匀会影响性能。
- 【易错点 1】只重写 equals 不重写 hashCode,导致集合中对象无法正确匹配。
- 【易错点 2】使用可变字段参与 equals/hashCode 计算,对象放入集合后修改字段可能导致 HashSet 中无法删除或查找。
- 【易错点 3】误将 == 用于字符串比较,比较的是引用而非内容。