关于hashcode()和equals()的用法

本文通过一个例子解释了在Java中,为何在自定义类中重写equals()和hashCode()方法是必要的。当HashSet存储对象时,如果不重写这两个方法,可能会导致相同对象的多个实例被视为不同元素。详细分析了默认的equals()和hashCode()行为,以及如何通过重写确保正确地比较和存储对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于hashcode和equals的用法与具体区别,我想通过如下例子引入。

首先,我设计一个HashSetTest类和一个Student类,在HashSetTest中添加4个Student的实例,其中第四个和第一个实例的number和name都一样,所以是相同元素。按照HashSet不能有重复元素的性质,最终输出的答案当中,Student0不会出现两次(第二个Student0作为重复元素被忽略)。

然而。实际的结果却是出乎意料的,最终输出如下:

我们看到,两次Student0都被add进了HashSet当中。原因是什么?我们自己写的Student类并没有重新自己的hashcode()和equals()方法,所以在比较时,是继承的object类中的hashcode()方法,而object类中的hashcode()方法是一个本地方法,比较的是对象的地址(引用地址),使用new方法创建对象,两次生成的当然是不同的对象了,hashcode()的返回原则是:如果地址一样就返回true,不一样就返回false。如此一来,在add时对add的元素进行比较时,由于调用的是未经重写的hashcode(),所以比较的其实是元素的地址,由于第四次add的那个student显然和第一次add的student地址不同,所以hashcode()偷偷返回了false(我们期望它返回true!)。

因此,重写Student类中的equal()和hashcode()就显得非常重要了。

现在进行如下的重写:

再次运行HashSetTest,就得到了预期的结果。

在java的集合中,判断两个对象是否相等的规则是:
         1.判断两个对象的hashCode是否相等

             如果不相等,两个对象不相等
             如果相等,转入2

         2.判断两个对象用equals运算是否相等
            如果不相等,两个对象不相等
            如果相等,两个对象相等(equals()是判断两个对象是否相等的关键)


可以进一步推断出如下的结论:

1、相等(相同)的对象必须具有相等的哈希码(或者散列码)。

2、如果两个对象的hashCode相同,它们并不一定相同。

第一点很好理解,两个相同的对象,他们的哈希码如果不一样,他们在哈希表中就存放在两个不同的位置,这与哈希表无重复元素的性质矛盾。所以他们哈希码必定相同。

第二点,两个对象的哈希码相同,意味着他们存在哈希表的同一个位置,并不能保证他们是相同的。(因为即使他们不同也可以在哈希表的同一个位置用链表连接起来)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值