这段话的核心其实就一句:
hashCode() 负责快速找到对象可能在哪,** equals() 负责最终确认是不是同一个“逻辑对象”。
可以结合 HashMap 来理解。
假设:
Person p1 = new Person(1, "张三");
Person p2 = new Person(1, "张三");我们重写了方法,规定:id 和 name 一样,就认为两个 Person 相等。
那么:
p1.equals(p2) // true既然逻辑上已经认为它们相等,那么:
p1.hashCode() == p2.hashCode()也必须成立。
为什么必须这样?
因为 HashMap 查找一个 key,大致是:
key
↓
① 计算 hashCode
↓
② 根据 hashCode 找到对应位置/桶
↓
③ 再使用 equals 比较
↓
④ 确认是不是要找的对象假如出现这种情况:
p1.equals(p2) = true
但是:
p1.hashCode() = 100
p2.hashCode() = 200那么它们可能被分到不同的桶:
HashMap
桶1 ← p1(hashCode = 100)
桶2 ← p2(hashCode = 200)这就出问题了:明明 equals() 认为它俩一样,HashMap 却可能根本不会到同一个地方比较它们。
而反过来:
p1.hashCode() == p2.hashCode()不能说明:
p1.equals(p2) == true因为 hashCode() 只有 int 这么大的取值范围,而对象可以有无数种,所以不同对象完全可能算出同一个数字。
例如:
Person A → hashCode = 666
Person B → hashCode = 666
但:
A.equals(B) → false这就是哈希冲突。
所以八股直接记这三句话:
① equals 相等 → hashCode 必须相等。
② hashCode 相等 → equals 不一定相等,因为可能哈希冲突。
③ HashMap 中 hashCode 用于快速定位,equals 用于最终确认。
因此,重写 equals()时必须配套重写hashCode(),让二者的“相等标准”保持一致。