为什么重写equals()方法时必须重写hashCode()方法?

8,395次阅读
没有评论

共计 2003 个字符,预计需要花费 6 分钟才能阅读完成。

社会主义接班人
2024-02-23 09:39:18
浏览数 (2424)

在 Java 中,当我们在类中重写 equals() 方法来比较对象的相等性时,必须同时重写 hashCode() 方法。本文将解释为什么这两个方法需要一起重写,并讨论它们之间的关系以及为什么违反这个规则可能导致问题。

images

equals() 和 hashCode() 的关系

在 Java 中,​equals()​方法被用于比较对象的相等性,而​hashCode()​方法则用于生成对象的哈希码。这两个方法在处理对象的相等性时密切相关。根据 Java 规范,如果两个对象通过​equals()​方法相等,那么它们的​hashCode()​方法必须返回相同的值。因此,当我们重写​equals()​方法来定义对象的相等条件时,为了遵循这个规则,也必须重写​hashCode()​方法。

hashCode() 的作用

hashCode()​方法的作用是返回一个整数值,它用于支持基于哈希表的数据结构,如 HashMap、HashSet 等。这些数据结构在存储对象时使用哈希码来快速定位对象。当我们将对象存储在哈希表中时,首先会根据对象的哈希码计算出一个索引位置,然后在该位置上进行查找或存储操作。如果两个对象通过​equals()​方法相等但它们的​hashCode()​方法返回不同的值,那么它们可能会被错误地存储在不同的位置,导致无法正确地获取或比较这些对象。

一致性的重要性

为了解决哈希表等数据结构中的问题,Java 规范要求​equals()​方法和​hashCode()​方法在逻辑上保持一致。具体来说,如果两个对象通过​equals()​方法相等,那么它们的​hashCode()​方法必须返回相同的值。这确保了当我们将这些对象存储在哈希表中时,它们会被正确地放置在相应的位置上。当我们使用​equals()​方法来比较对象相等性时,通常是首先比较它们的哈希码,然后再比较它们的具体属性,以提高效率。

违反一致性规则的后果

违反​equals()​和​hashCode()​的一致性规则可能导致一些问题。例如,如果我们将一个对象添加到 HashSet 或 HashMap 中,并且后续尝试使用另一个相等的对象查找或删除它,由于哈希码不同,我们将无法正确地找到该对象。这会导致数据结构中存在重复的对象或无法正确地操作对象。

正确重写 equals() 和 hashCode() 的指导原则

为了正确地重写​equals()​和​hashCode()​方法,我们可以遵循以下指导原则:

  • equals()​方法的重写应该基于对象的内容,而不仅仅是基于引用的相等性。比较对象的属性值来确定它们是否相等。
  • hashCode()​方法的重写应该与​equals()​方法的比较条件保持一致。即,如果两个对象通过​equals()​方法相等,它们的​hashCode()​方法应该返回相同的值。
  • 如果在类中使用可变的属性作为​equals()​和​hashCode()​方法的比较依据,确保在修改这些属性时同时更新​hashCode()​的计算,以保持一致性。
  • 使用 IDE 工具(如 Eclipse、IntelliJ IDEA)可以自动生成​equals()​和​hashCode()​方法的模板代码,避免手动编写时出现错误。

示例代码

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 重写 equals() 方法
    @Override
    public boolean equals(Object obj) {if (this == obj) {return true;}
        if (obj == null || getClass() != obj.getClass()) {return false;}
        Person person = (Person) obj;
        return age == person.age && Objects.equals(name, person.name);
    }

    // 重写 hashCode() 方法
    @Override
    public int hashCode() {return Objects.hash(name, age);
    }
}

总结

在 Java 中,重写​equals()​方法时必须同时重写​hashCode()​方法,以保证这两个方法的一致性。违反这个规则可能导致对象无法正确地存储和比较。通过正确地重写这两个方法,我们可以确保对象在使用哈希表等数据结构时能够正常运行,并且能够正确地比较对象的相等性。因此,在设计类时,务必记得同时重写​equals()​和​hashCode()​方法,以遵循 Java 规范并确保代码的正确性和可靠性。

原文地址: 为什么重写 equals() 方法时必须重写 hashCode() 方法?

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-09-19发表,共计2003字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)