java中equals和hashCode为什么要一起重写

文章目录


equals()方法

equals() 方法是 java.lang.Object 类的一个方法,它用于比较两个对象是否相等。默认情况下,Object 类中的 equals() 方法是通过判断对象的引用是否相等来实现的,也就是说,它比较的是对象在内存中的地址。如果你需要判断两个对象的内容是否相等,你需要重写 equals() 方法。

常见的重写规则:

  • 自反性 :对于任何非 null 的对象 xx.equals(x) 必须返回 true
  • 对称性 :对于任何非 null 的对象 xy,如果 x.equals(y) 返回 true,那么 y.equals(x) 也必须返回 true
  • 传递性 :对于任何非 null 的对象 xyz,如果 x.equals(y) 返回 truey.equals(z) 返回 true,那么 x.equals(z) 也必须返回 true
  • 一致性 :对于任何非 null 的对象 xy,如果 x.equals(y) 返回 true,那么每次调用 x.equals(y) 都必须返回 true,除非对象的状态发生了改变。
  • null 的处理 :任何对象与 null 比较时都应该返回 false

示例

java 复制代码
class Person {
    private String name;
    private int age;

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true; // 引用相同,直接返回true
        if (obj == null || getClass() != obj.getClass()) return false; // 类型不同或对象为空,返回false
        Person person = (Person) obj; // 转换类型
        return age == person.age && name.equals(person.name); // 比较属性
    }
}

hashCode()方法

hashCode() 方法是 java.lang.Object 类的一个方法,返回一个整数值(哈希码),用于表示对象的内存地址(但并不完全是内存地址)。哈希码用于在基于哈希的集合(如 HashMapHashSet 等)中确定对象的位置。

基本规则:

  • 如果两个对象通过 equals() 比较返回 true,那么它们的 hashCode() 也必须相同。
  • 对于相同的对象,每次调用 hashCode() 应该返回相同的值。
  • 如果两个对象的 equals() 返回 false,那么它们的 hashCode() 不一定要不同,但是不同的哈希码可以提高哈希表的性能(避免哈希冲突)。

为什么通常需要一起重写 equals()hashCode()

一致性要求

  • Java的集合框架(如 HashSetHashMap 等)基于哈希值来存储和查找元素。在这些集合中,首先使用 hashCode() 来定位对象可能存储的位置。如果 hashCode() 不一致或不正确,可能导致相等的对象被存储到不同的位置,从而影响性能和正确性。
  • hashCode() 的值用来找到对象在集合中的位置,而 equals() 用于实际比较两个对象是否相等。如果这两个方法不一致,就会违反集合框架的基本要求,导致对象查找、删除或更新的异常行为。

哈希表的工作原理

  • 在哈希表中,两个相等的对象应该具有相同的哈希值,以便在相同的桶中进行存储和比较
  • 如果两个对象的 equals() 返回 true,那么它们必须具有相同的 hashCode(),否则集合框架会误认为它们是不同的对象,导致查找或删除失败。

避免错误的行为

  • 比如,在 HashSet 中,添加一个新的对象时,如果它与已经存在的对象相等(即 equals() 返回 true),就不应该再添加。如果只重写了 equals() 而没有重写 hashCode(),即使两个对象的内容相同,它们也可能被认为是不同的,从而导致错误的添加操作。

例子说明

假设有一个 Person 类,它的 equals() 方法比较 nameage 属性。如果不重写 hashCode(),当我们将两个 Person 对象添加到一个 HashSet 中时,如果这两个对象的 nameage 相同,它们在 equals() 上应该返回 true,但如果它们的 hashCode() 不相同,HashSet 会认为它们是两个不同的对象,从而错误地添加两个相同的对象。

总结

  • equals() 用于判断两个对象的"内容"是否相等,而 hashCode() 用于计算对象的哈希码,帮助集合类确定对象的位置。
  • 根据 Java 的集合框架约定,如果两个对象相等(即 equals() 返回 true),它们的 hashCode() 必须相同。
  • 因此,为了确保集合框架的正确行为,通常需要同时重写这两个方法。如果只重写了其中一个,可能导致集合类行为不正确。
相关推荐
未定义.2216 分钟前
电子削铅笔刀顺序图详解:从UML设计到PlantUML实现
java·软件工程·uml
雾月5523 分钟前
LeetCode 1292 元素和小于等于阈值的正方形的最大边长
java·数据结构·算法·leetcode·职场和发展
hnlucky29 分钟前
redis 数据类型新手练习系列——Hash类型
数据库·redis·学习·哈希算法
24k小善1 小时前
Flink TaskManager详解
java·大数据·flink·云计算
想不明白的过度思考者1 小时前
Java从入门到“放弃”(精通)之旅——JavaSE终篇(异常)
java·开发语言
天天扭码2 小时前
总所周知,JavaScript中有很多函数定义方式,如何“因地制宜”?(ˉ﹃ˉ)
前端·javascript·面试
.生产的驴2 小时前
SpringBoot 封装统一API返回格式对象 标准化开发 请求封装 统一格式处理
java·数据库·spring boot·后端·spring·eclipse·maven
猿周LV2 小时前
JMeter 安装及使用 [软件测试工具]
java·测试工具·jmeter·单元测试·压力测试
晨集2 小时前
Uni-App 多端电子合同开源项目介绍
java·spring boot·uni-app·电子合同
时间之城2 小时前
笔记:记一次使用EasyExcel重写convertToExcelData方法无法读取@ExcelDictFormat注解的问题(已解决)
java·spring boot·笔记·spring·excel