前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为什么重写 equals() 时必须重写 hashCode() 方法?(简单易理解)

为什么重写 equals() 时必须重写 hashCode() 方法?(简单易理解)

作者头像
人不走空
发布2024-02-20 19:23:11
1280
发布2024-02-20 19:23:11
举报
文章被收录于专栏:学习与分享学习与分享

Object 的 equals() 默认比较的是对象的内存地址 hashCode() 也是对对象的内存地址进行hash。

所以在涉及到hashcode的容器中(比如HashSet),判断自己是否持有该对象时,会先检查hashCode是否相等,如果hashCode不相等,就会直接认为不相等,并存入容器中,不会再调用equals进行比较。

但是hashCode()会出现哈希冲突,当发现哈希冲突时,便需要equals方法进行判断两者是否相等

如果重写了equals方法,相等的元素内存地址不一定相等。若不重写hashcode,还是可能会发生元素相同问题。所以要重写hashCode()。因此要重写hashCode保证:如果equals判断是相等的,那hashCode值也要相等。

哈希冲突:不同数值却拥有相同哈希值。

在Java中,equals() 方法用于比较对象的内容是否相等,而 hashCode() 方法用于获取对象的哈希码。这两个方法在某些场景下是紧密关联的,尤其是在使用哈希集合(如 HashMapHashSet)时。在这篇博客中,我们将深入探讨为什么在重写 equals() 方法的同时必须重写 hashCode() 方法。

相等对象应该有相等的哈希码

在Java中,如果两个对象通过 equals() 方法判断相等,那么它们的哈希码应该相等。反之亦然,即如果两个对象的哈希码相等,它们不一定通过 equals() 方法判断相等。

为什么要保持这种关系呢?原因在于哈希集合的实现,比如 HashMap。这些集合通过哈希码来确定对象在内部数据结构中的存储位置。当我们尝试查找某个对象时,先根据哈希码定位到可能的存储位置,然后再通过 equals() 方法来确保找到的是真正相等的对象。

如果两个相等的对象具有不同的哈希码,那么它们将被存储在不同的位置,导致无法正确地通过 equals() 方法找到这些对象。

重写 equals() 的常见场景

1.类表示值: 如果一个类的实例是不可变的,并且表示值(如字符串、数字),那么通常需要重写 equals() 方法。

代码语言:javascript
复制
@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null || getClass() != obj.getClass()) return false;
    MyClass myObject = (MyClass) obj;
    return Objects.equals(value, myObject.value);
}

2. 自定义类: 自定义类需要比较对象的内容时,也需要重写 equals() 方法。

代码语言:javascript
复制
@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()

在Java中,hashCode() 方法返回对象的哈希码,它在哈希集合中起着关键的作用。当我们将对象放入哈希集合时,集合通过对象的哈希码来决定对象的存储位置。

如果我们在重写了 equals() 方法的同时不重写 hashCode() 方法,可能导致以下问题:

  1. 相等对象哈希码不同: 如果两个对象通过 equals() 判断相等,但它们的哈希码不同,这将违反哈希集合的原则,导致无法正确处理相等对象。
  2. 相同哈希码不等对象: 如果两个对象的哈希码相等,但它们通过 equals() 判断不相等,这可能导致哈希集合中存储重复的对象,破坏集合的正确性。

因此,为了确保哈希集合正常运作,必须同时重写 equals()hashCode() 方法。这可以通过IDE(如Eclipse、IntelliJ IDEA)提供的工具来自动生成。

重写 hashCode() 的实例

代码语言:javascript
复制
@Override
public int hashCode() {
    return Objects.hash(name, age);
}

这个例子中,使用 Objects.hash() 方法来组合多个属性的哈希码,以确保生成的哈希码是基于所有相关属性的。这有助于避免相等对象的哈希码不同的问题。

总结

在Java中,equals()hashCode() 方法的正确实现对于正确使用集合类非常重要。通过保持相等对象具有相等的哈希码,我们可以确保哈希集合的正确性,防止发生数据结构中的问题。因此,在重写 equals() 方法时,务必同时重写 hashCode() 方法,以维护良好的编程实践。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 相等对象应该有相等的哈希码
  • 重写 equals() 的常见场景
  • 为什么必须重写 hashCode()
  • 重写 hashCode() 的实例
  • 总结
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档