equals()和hashcode()

在这里插入图片描述
原文链接

先案例后讲解,这里是代码教父,今天讲解JAVA中的equals和hashcode

先案例后讲解,这里是代码教父,今天讲解JAVA中的equals和hashcode

[1] equals 和 hashcode是什么

在Java中,equals()和hashCode()是Object类中的两个方法,它们用于处理对象之间的相等性比较和哈希值计算。

equals()方法用于比较两个对象是否相等。根据默认实现,它比较的是对象的引用是否相等,即比较两个对象是否是同一个实例。但是,通常情况下,我们需要根据对象的属性来确定它们是否相等,因此,我们需要重写equals()方法。在重写equals()方法时,通常要满足以下几个条件:

  1. 自反性:对于任何非null的引用值x,x.equals(x)应返回true。
  2. 对称性:对于任何引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)应返回true。
  3. 传递性:对于任何引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)返回true,那么x.equals(z)应返回true。
  4. 一致性:对于任何非null的引用值x和y,只要对象的属性没有更改,多次调用x.equals(y)应始终返回相同的结果。
  5. 对于任何非null的引用值x,x.equals(null)应返回false。

hashCode()方法用于计算对象的哈希值。哈希值是一个整数,用于在哈希表等数据结构中快速定位对象。根据Object类的默认实现,hashCode()返回对象的内存地址。当我们重写equals()方法时,通常也需要重写hashCode()方法,以保证如果两个对象相等,则它们的哈希值也相等。在重写hashCode()方法时,通常要满足以下几个条件:

  1. 如果两个对象相等,则它们的hashCode()值一定相等。
  2. 两个对象的hashCode()值相等,并不意味着它们一定相等。

在Java中,equals()和hashCode()方法常常需要同时被重写,以保证对象相等性的正确性。

[2]如何实现equals和hashcode

要实现equals()和hashCode()方法,你可以按照以下步骤进行操作:

  1. 重写equals()方法:
    • 确定你希望用于比较相等性的属性,这些属性应该包括在equals()方法的比较中。
    • 检查是否比较的是同一个对象,如果是,直接返回true。
    • 检查对象是否为null,或者是否是与你的类不兼容的类型,如果是,返回false。
    • 使用instanceof关键字检查两个对象是否属于同一类。
    • 将对象强制转换为你的类类型。
    • 逐个比较对象的属性,如果所有属性都相等,返回true,否则返回false。
  2. 重写hashCode()方法:
    • 定义一个hashCode变量,并初始化为一个非零奇数。
    • 对每个参与equals()比较的属性,计算它们的哈希码并结合到hashCode变量中,可以使用Objects类的hash()方法或者自定义方式。
    • 返回计算得到的hashCode变量。

下面是一个示例,展示了如何在一个简单的Person类中实现equals()和hashCode()方法:

import java.util.Objects;

public class Person {
    private String name;
    private int age;

    // 构造函数、getter和setter方法省略

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

在上面的示例中,equals()方法比较了name和age属性是否相等,hashCode()方法计算了name和age的哈希码并结合。记得在equals()方法中使用Objects.equals()来比较属性,以处理null值的情况。

请注意,重写equals()和hashCode()方法时需要遵循上文提到的条件和原则,以确保正确性和一致性。

[3]== 和equals的区别

"=="运算符和equals()方法是用于比较对象之间相等性的两种方式,它们的区别如下:

  1. "=="运算符:
    • "=="运算符用于比较两个对象的引用是否相等,即比较对象在内存中的地址是否相同。
    • 当使用"=="比较基本类型时,比较的是它们的值是否相等。
    • 当使用"=="比较引用类型时,比较的是引用变量中保存的地址值是否相等。
  2. equals()方法:
    • equals()方法是Object类的方法,在许多类中被重写以用于比较对象的逻辑相等性。
    • 默认情况下,equals()方法和"=="运算符作用相同,即比较引用是否相等。
    • 但是,可以根据需要在类中重写equals()方法,按照自定义的逻辑判断两个对象是否相等。
    • 通常在重写equals()方法时,也会同时重写hashCode()方法。

所以:

  • "=="运算符比较的是引用的地址值,用于判断两个对象是否是同一个实例。
  • equals()方法比较的是对象的逻辑相等性,通常需要根据对象的属性进行判断。

所以,如果你希望判断两个对象是否相等,通常应该使用equals()方法来进行比较,而不是"“运算符。但请注意,如果你没有在类中重写equals()方法,默认情况下它和”"运算符的效果是一样的。

[4]为什么要有hashCode

hashCode在Java中的作用主要有两个方面:

  1. 哈希表性能优化:
    • 在Java中,哈希表(例如HashMap、HashSet)是基于哈希码的数据结构,用于高效地存储和查找对象。
    • hashCode()方法用于计算对象的哈希值,它将对象映射到一个整数,作为对象在哈希表中的索引。
    • 计算哈希码时,通常使用对象的属性值,以保证相等的对象具有相同的哈希码,从而提高哈希表的查找效率。
    • 在哈希表进行查找时,首先根据对象的哈希码定位到对应的位置,然后再用equals()方法比较对象是否相等。
  2. 对象的散列性质:
    • hashCode()方法返回的哈希码具有散列性质,即不同对象的哈希码尽量不相同,减少哈希冲突的概率。
    • 哈希冲突是指不同的对象计算得到的哈希码相同,在哈希表中占用相同的位置,需要进行额外的处理。
    • 好的哈希码分布可以减少哈希冲突的发生,从而提高哈希表的性能。
    • hashCode方法的实现应该尽量满足均匀分布的特性,不同对象之间尽可能计算得到不同的哈希码。

总之,hashCode的存在可以提高哈希表的性能,使对象能够更高效地存储和检索,并且良好的哈希码分布可以减少哈希冲突的发生,提高哈希表的性能和效率。

[5]为什么重写equals时必须重写hashCode方法

在Java中,如果你重写了equals()方法,就必须同时重写hashCode()方法,不仅仅是为了遵循一致性规则,还有以下两个重要的原因:

  1. 保证对象在哈希表中的一致性:
    • 哈希表(例如HashMap、HashSet)在查找和存储对象时,首先会根据对象的哈希码(通过调用hashCode()方法)来确定对象在哈希表中的位置。
    • 如果两个对象在equals()方法中被判断为相等,则它们在哈希表中应该是等效的。
    • 如果两个对象在equals()方法中相等(即逻辑相等),但它们的hashCode()方法返回的哈希码不一样,会导致哈希表无法正确地处理它们,可能导致哈希表中存储重复的对象或无法正确定位对象。
    • 因此,在重写equals()方法时,也必须重写hashCode()方法,以保证逻辑上相等的对象具有相同的哈希码,从而保证它们能够正确处理在哈希表中的一致性。
  2. 符合对象相等性的约定:
    • 根据Java规范,如果两个对象在equals()方法比较时返回相等,那么它们的hashCode()方法必须返回相同的值。
    • 这个约定确保了,如果两个对象逻辑上相等(equals()返回true),则它们在哈希表中的哈希码也必须相等,从而能够正确地在哈希表中查询和比较对象。
    • 如果只重写了equals()方法而没有重写hashCode()方法,会导致违反了这个约定,可能导致在使用哈希表的场景下出现意料之外的结果。

因此,为了保证对象在哈希表中的一致性并满足对象相等性的约定,重写equals()方法时必须同时重写hashCode()方法,确保两个方法的逻辑一致性,并保证对象能够正确参与哈希表的操作。

[6]总结

  1. 逻辑相等的对象应该具有相同的哈希码:
    • 根据Java规范,如果两个对象在equals()方法比较时返回相等(逻辑相等),则它们的hashCode()方法必须返回相同的值。
    • 这个约定保证了对象在哈希表中的一致性,即在哈希表中查找和比较对象时能够正确工作。
  2. hashCode()方法影响哈希表的性能:
    • hashCode()方法用于计算哈希码,将对象映射到一个整数值作为对象在哈希表中的索引位置。
    • 在哈希表中存储和查找对象时,根据对象的哈希码定位到对应的位置,减少比较的次数,提高存储和检索的效率。
    • 因此,好的hashCode()方法实现能够使得对象在哈希表中更均匀地分布,减少哈希冲突的概率,提高哈希表的性能。
  3. 重写equals()方法必须同时重写hashCode()方法:
    • 如果你重写了equals()方法以定义对象的逻辑相等性,就应该同时重写hashCode()方法,以保持逻辑上相等的对象具有相同的哈希码。
    • 这样做是为了避免在使用哈希表的时候出现意外的结果,保证对象在哈希表中正确存储、查找和比较。

综上所述,equals()方法和hashCode()方法之间的关系是:

  • 逻辑相等的对象应该具有相同的哈希码,以保证在哈希表中的一致性。
  • hashCode()方法的实现能够影响哈希表的性能。
  • 如果你重写了equals()方法,就必须同时重写hashCode()方法,以保持对象的一致性,并确保正确参与哈希表的操作。

更多精彩,敬请关注“公众号: 代码教父”

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值