区别:
equals()方法用于比较两个对象是否相等。默认情况下(从Object类继承),它比较的是两个对象的引用是否指向同一内存地址。但通常我们会重写它,以便根据对象的内容(即属性值)来比较是否相等。
hashCode()方法返回对象的哈希码值,主要用于支持哈希表(如HashMap、HashSet等)的高效性能。默认情况下,hashCode()返回对象的内存地址的整数形式。
几乎在所有情况下,如果一个类重写了 equals 方法,那么它也必须重写 hashCode 方法。 这是一个在 Java 中非常重要且必须遵守的契约,定义在 Object 类的规范中。
String、Integer、Long、LocalDate 等所有标准的 Java 类库中的值类都严格遵守了这条规则。
为什么重写equals()就要重写hashCode():
这是因为Java规范中规定:如果两个对象根据equals()方法比较是相等的,那么它们的hashCode()方法必须返回相同的整数。反之,如果两个对象的hashCode()返回相同的值,它们不一定相等(因为哈希冲突可能发生)。
这一规定主要是为了确保哈希表(如HashMap、HashSet等)的正确工作。哈希表使用哈希码来快速定位元素,如果两个相等的对象返回不同的哈希码,那么将它们放入哈希表(例如作为键)时,可能会导致无法正确找到之前放入的对象,从而违反哈希表的设计原则。
举个例子:假设我们重写了某个类的equals()方法,使得两个属性相同的对象被认为是相等的,但没有重写hashCode()方法。那么这两个对象可能返回不同的哈希码(因为默认的hashCode()与内存地址相关)。当我们将第一个对象放入HashSet后,再尝试用第二个对象(与第一个对象相等)去检查HashSet是否包含它时,由于哈希码不同,HashSet可能在错误的哈希桶中查找,从而返回false,尽管这两个对象是相等的。
因此,为了保证在使用哈希表时对象行为一致,重写equals()方法时通常也需要重写hashCode()方法,并确保相等的对象具有相等的哈希码。
如何重写:
重写equals()方法时,通常比较对象的所有相关属性。
重写hashCode()方法时,通常使用相同的属性来计算哈希码,可以使用Java中的Objects.hash()方法来简化。