为什么说重写equals时要重写hashcode

简介: 为什么说重写equals时要重写hashcode



       当我们在Java中创建一个类,并希望在集合类(如HashMapHashSet等)中使用这个类的实例时,通常需要重写equals方法。但为什么要同时重写hashCode方法呢?

       我们先了解一下equal和hashCode。

equal 和 hashCode 是什么?


       在Java中,equals方法是Object类中定义的一个方法,用于比较两个对象是否在逻辑上相等。

为什么要重写equals方法

       默认情况下,equals方法在Object类中的实现是比较两个对象的引用是否相等,即它们是否指向内存中的同一位置。这意味着,如果你创建了两个相同内容的对象,它们的equals方法可能返回false,因为它们在内存中的位置不同。但在很多情况下,我们更关心的是对象的内容是否相等,而不是对象的引用是否相等。

  hashCode 是 Java 中 Object 类的一个方法,用于返回对象的哈希码。哈希码是一个32位的整数,它代表了对象的内存地址经过哈希算法生成的值。每个对象都有一个对应的哈希码。哈希码的主要作用是在集合类中,比如HashMapHashSet等,用于快速定位对象的位置。

       在 Java 中,hashCode 方法的定义在 Object 类中,但是它通常会被子类重写以提供更有意义的哈希码。如果两个对象根据 equals 方法是相等的,那么它们的 hashCode 方法应该返回相同的值。虽然相等的对象必须具有相等的哈希码,但相等哈希码的对象并不一定相等。

那么为什么需要重写hashCode方法呢?

       默认情况下,两个相等的对象(根据equals方法的定义)的哈希码可能是不相等的,这违反了集合的规则。但是我们希望相等的对象具有相等的哈希码。

       集合类在处理冲突或者寻找对象时,会先根据哈希码定位到可能的位置,然后再使用equals方法来准确地找到对象。如果两个相等的对象的哈希码不同,它们可能会被放置在不同的位置,导致无法正确地找到对象。

       下面是一个示例:

public static void main(String[] args) {
    Person p1=new Person("张三",21);
    Person p2=new Person("张三",21);
    
    Set<Person> set=new HashSet<>();
    set.add(p1);
    
    System.out.println(set.contains(p2));//是否包含p2对象,返回false
    
  }

       尽管 p1p2的内容相同,但由于它们具有不同的哈希码,set.contains(p2) 返回 false。这是因为哈希表无法正确定位到p2。

为什么要保持equals和hashCode的一致性?


       当我们在集合类中使用对象时,通常是先使用hashCode定位到对象的位置,然后再使用equals方法确保找到的对象是真正相等的。为了保持这一过程的正确性,equalshashCode方法之间需要保持一致性。

一致性规则

       如果两个对象根据equals方法是相等的,那么它们的hashCode方法应该返回相同的值。反之,如果两个对象的hashCode相等,它们不一定要相等。

重写hashcode和equals示例


public class Student {
    private String name;
    private int age;
    // 构造方法、其他方法等...
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }
    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
}

       在这个示例中,equals方法根据nameage的内容来判断两个Student对象是否相等,而hashCode方法则根据nameage的内容生成哈希码。这样,如果两个Student对象根据equals方法是相等的,它们的hashCode值也会相等,从而保持了一致性。

相关文章
|
7月前
|
存储 算法 Java
为什么要重写 hashcode 和 equals 方法
为什么要重写 hashcode 和 equals 方法
61 0
|
2月前
|
存储 算法 Java
为什么重写 equals 方法时必须同时重写 hashCode 方法?
本文探讨了 Java 中 `hashCode` 方法的作用及其与 `equals` 方法的关系,解释了为什么重写 `equals` 方法时必须同时重写 `hashCode` 方法,并提供了如何正确重写 `hashCode` 方法的示例。
|
存储
重写equals后为什么要重写hashcode方法
重写equals后为什么要重写hashcode方法
69 0
|
7月前
|
存储 Java
为什么要重写hashCode()和equals()(深入了解)
为什么要重写hashCode()和equals()(深入了解)
|
7月前
|
存储 IDE Java
为什么重写 equals() 时必须重写 hashCode() 方法?(简单易理解)
为什么重写 equals() 时必须重写 hashCode() 方法?(简单易理解)
51 1
|
存储
为什么重写 equals 方法就必须重写 hashCode 方法?
为什么重写 equals 方法就必须重写 hashCode 方法?
81 0
|
存储 Java
重写equals方法
我们在java程序中调用自带的equals方法时,你是否会有这样的疑问:明明我比较的数据都一样啊,为什么会返回false呢?有些人可能还会疑问,怎么有时候返回true?有时候返回false呢?这是为什么呢?其实是和Java底层人家写的equals方法逻辑有关系
为什么要重写 hashcode 和 equals 方法?
为什么要重写 hashcode 和 equals 方法?
85 0
|
Oracle Java 关系型数据库
为什么重写 equals() 方法,一定要重写 hashCode() 呢?| HashMap
首先我们有一个假设:任何两个 object 的 hashCode 都是不同的。 那么在这个条件下,有两个 object 是相等的,那如果不重写 hashCode(),算出来的哈希值都不一样,就会去到不同的 buckets 了,就迷失在茫茫人海中了,再也无法相认,就和 equals() 条件矛盾了,证毕。
154 0
为什么重写 equals() 方法,一定要重写 hashCode() 呢?| HashMap
|
存储 算法 Java
(强制)要求覆写equals必须覆写hashCode(原理分析)
hashCode和equals hashCode和equals用来标识对象,两个方法协同工作可用来判断两个对象是否相等。众所周知,根据生成的哈希将数据散列开来,可以使存取元素更快。对象通过调用Object.hashCode()生成哈希值;由于不可避免会存在哈希值冲突 的情况,因此当hashCode相同时,还需要再调用equals进行一次值的比较;但是若hashCode不同,将直接判定Object不同,跳过equals,这加快了冲突处理效率。Object类定义中对hashCode和equals要求如下:
244 0