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

简介: 当hashCode相同时,equals是否也相同?

在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类保证了内容相同的字符串具有相同的哈希值。但在更一般的情况,这不一定成立。


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


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


总结


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


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


目录
相关文章
|
6天前
|
存储 算法 Java
为什么要重写 hashcode 和 equals 方法
为什么要重写 hashcode 和 equals 方法
25 0
|
6天前
|
存储 Java
为什么要重写hashCode()和equals()(深入了解)
为什么要重写hashCode()和equals()(深入了解)
|
6天前
|
存储 Java 对象存储
当hashCode相同时,equals是否也相同?
当hashCode相同时,equals是否也相同?
36 0
|
10月前
为什么要重写 hashcode 和 equals 方法?
为什么要重写 hashcode 和 equals 方法?
57 0
|
存储 NoSQL
简单讲一下 HashCode() 与 equals()方法
简单讲一下 HashCode() 与 equals()方法.
88 0
hashCode和equals的区别
hashCode和equals的区别
288 0
|
Java 索引
hashCode和equals的区别(一)
Hello,大家好,我是子悠,作为本周的小编我已经不想跟大家介绍自己了,这篇文章让我们跟随 Jay Pan( 哇,一位新作者哦)的步伐学习知识吧。下面是正文。 有面试官会问:你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?equals和hashCode都是Object对象中的非final方法,它们设计的目的就是被用来覆盖(override)的,所以在程序设计中还是经常需要处理这两个方法。下面我们一起来看一下,它们到底有什么区别,总结一波!
|
测试技术
hashCode和equals的区别(二)
Hello,大家好,我是子悠,作为本周的小编我已经不想跟大家介绍自己了,这篇文章让我们跟随 Jay Pan( 哇,一位新作者哦)的步伐学习知识吧。下面是正文。 有面试官会问:你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?equals和hashCode都是Object对象中的非final方法,它们设计的目的就是被用来覆盖(override)的,所以在程序设计中还是经常需要处理这两个方法。下面我们一起来看一下,它们到底有什么区别,总结一波!
|
存储 缓存 算法
关于 equals 和 hashCode,看这一篇真的够了!
这几天在尝试手撸一个类似Lombok的注解式代码生成工具,用过Lombok的小伙伴知道,Lombok可以通过注解自动帮我们生产equals()和hashCode()方法,因此我也想实现这个功能,但是随着工作的深入,我发现其实自己对于equals()和hashCode()的理解,也处在一个很低级的阶段。
关于 equals 和 hashCode,看这一篇真的够了!
|
存储 算法 Java
equals 和 hashCode 到底有什么联系?
写在前面 Java的基类Object提供了一些方法,其中equals()方法用于判断两个对象是否相等,hashCode()方法用于计算对象的哈希码。equals()和hashCode()都不是final方法,都可以被重写(overwrite)。
equals 和 hashCode 到底有什么联系?