必须配套重写equals,因为Java规定:若a.equals(b)为true,则a.hashCode()必须等于b.hashCode();否则HashMap、HashSet等会因哈希不一致导致查找失败或重复添加。

重写 hashCode 必须和 equals 一起配套重写,否则会破坏哈希集合(如 HashMap、HashSet)的正确性。
为什么必须配套重写 equals?
Java 规定:如果两个对象通过 equals 判断为相等,那么它们的 hashCode 值也必须相等。反之不强制,但不相等的 hashCode 可提升性能。
如果不重写 hashCode,默认使用 Object.hashCode()(通常基于内存地址),会导致逻辑上相等的对象散列到不同桶中——HashMap 查不到、HashSet 重复添加,行为异常。
重写 hashCode 的核心原则
-
一致性:只要参与
equals比较的字段没变,多次调用hashCode必须返回相同整数 -
相等性约束:若
a.equals(b)为true,则a.hashCode() == b.hashCode()必须成立 - 尽量均匀分布:避免大量不同对象返回相同哈希值(减少哈希冲突)
推荐写法:用 Objects.hash(...)
最安全简洁的方式是使用 java.util.Objects.hash,它自动处理 null,并基于指定字段生成合理哈希值:
立即学习“Java免费学习笔记(深入)”;
public class Person {
private String name;
private int age;
private String idCard; // 可能为 null
<pre class='brush:java;toolbar:false;'>@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name) &&
Objects.equals(idCard, person.idCard);
}
@Override
public int hashCode() {
return Objects.hash(name, age, idCard); // 自动处理 null,无需手动判空
}}
手写 hashCode 的注意事项
如果不用 Objects.hash,需自行组合字段哈希值,常见模式如下:
- 初始值设为非零常量(如
result = 1) - 对每个关键字段:
result = 31 * result + field.hashCode() - 对基本类型(
int、boolean等),直接用其值;boolean建议转为1/0,double/float用Double.hashCode()转换 - 对可能为
null的引用字段,先判空再调用hashCode(),或用三元表达式(如field == null ? 0 : field.hashCode())


















