当hashCode相同时,equals是否也相同?

本文解释了Java中hashCode和equals方法的作用,特别强调了即使两个对象哈希码相同,它们通过equals比较也不一定相等,除非如String类那样实现了内容相关性。作者通过String类示例说明了如何处理哈希碰撞并保持一致性。
摘要由CSDN通过智能技术生成

 在Java中,理解对象的这两个基本方法—hashCode和equals对于编码是至关重要的,尤其是在处理集合类如HashMap和HashSet时。然而,一个常见的误解是,如果两个对象有相同的哈希码(hashCode),那么它们通过equals方法比较也一定相等。这其实是不正确的。在本博客中,我们将使用简单的String类示例来解释这个概念。

hashCode方法

   在Java中,hashCode方法是Object类的一个方法,每个Java对象都可以调用它。它返回一个整数值,由对象的内部地址、字段或者其他方式计算得出。但重要的是要记住,这个整数不必是唯一的。

  当你在像HashMap这样的哈希表中存储对象时,它实际上是存储在一个由这个哈希码索引标识的位置。所以一个好的hashCode实现会尽量保证对象的哈希码分布均匀,以减少碰撞(即两个不同的对象有相同的哈希码)。

equals方法

 equals方法则用来判断两个对象是否相等。在Object类中,默认的equals方法实际上只是比较两个对象的引用,也就是内存地址是否相同。然而,这个方法通常被重写来比较对象的内容是否相等。

String类的hashCode和equals

 String类重写了Object类的hashCode和equals方法。它的hashCode方法是根据字符串的内容计算出一个整数。而它的equals方法则是比较两个字符串的内容是否完全相同。

用String为例

  考虑以下Java代码段:

package org.example;
 
/**
 * @author YJH
 * @date 2024/1/3 16:37
 */
public class HashCodeEqualsExample {
    public static void main(String[] args) {
        String str1 = new String("hello");
        String str2 = new String("hello");
        String str3 = new String("world");
 
        System.out.println("str1 hashCode: " + str1.hashCode());
        System.out.println("str2 hashCode: " + str2.hashCode());
        System.out.println("str3 hashCode: " + str3.hashCode());
 
        System.out.println("str1 equals str2: " + str1.equals(str2));
        System.out.println("str1 equals str3: " + str1.equals(str3));
    }
}

 运行后得到的输出:

从中我们可以观察到以下几点:

当hashCode相同时

  1. str1 和 str2 拥有相同的哈希码,因为它们的内容是一样的。
  2. str1 和 str3 拥有不同的哈希码,因为它们的内容不一样。
  3. str1 和 str2 通过equals方法比较结果为true,因为它们的内容相同。
  4. str1 和 str3 通过equals方法比较结果为false,因为它们的内容不相同。

 现在,重点来了:如果两个字符串的hashCode相同,它们通过equals方法比较就一定相同吗?答案是:在这个String的示例中是如此,因为String类保证了内容相同的字符串具有相同的哈希值。但在更一般的情况,这不一定成立。

  因为哈希码是有限的,很有可能两个完全不同的对象—我们称它们为AB—有相同的哈希码(这称为哈希碰撞)。如何处理呢?如果对象AB存储在HashMap中,并且它们有相同的哈希码,HashMap会使用equals方法作为次级检查来确保正确地分辨对象。

这就是为什么当重写hashCode时,也应该重写equals方法以确保一致性。因为我们不能只依赖于哈希码来确定对象是否等价。

总结

  理解hashCodeequals方法以及它们之间的关系对正确使用Java非常关键。hashCode用于确定对象存储在哈希表中的地址,而equals用于确定对象的内容是否相等。记住,不同的对象可能有相同的哈希码,但通过equals方法不一定是相等的。我们需要确保这两个方法在我们的类中被正确地实现和使用。

通过简单的String实例,希望这篇博客能给初学者提供清晰的理解。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Y2000104

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值