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

目录

equal 和 hashCode 是什么?

为什么要重写equals方法

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

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

一致性规则

重写hashcode和equals示例


        当我们在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
		
	}

        尽管 p1 和 p2的内容相同,但由于它们具有不同的哈希码,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值也会相等,从而保持了一致性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

达芬奇要当程序员

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

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

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

打赏作者

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

抵扣说明:

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

余额充值