重写equals方法为什么要重写hashcode方法

首先明确一点:在使用集合时才有这个要求,其实如果不会用到集合可以不用严格遵循,但我们平常经常使用集合,所以一般就两者同时重写。

在了解为什么要一起重写之前,必须要了解2个概念:

1、==对于简单类型则是判断值是否相等,对于引用类型则是判断他们的地址是否相等

例子:

  1. int a=10;int b=10; a==b为true
  2. User a=new User(); User b=new User(); a==b为false
  3. User aa=new User("小明",20);User bb=new User("小明",20) ;aa==bb为false

有时我们希望3中,地址虽然不同,但是只要内容相同我们就认为两者相等,于是就要重写equals方法了。(equals方法默认和==一样,只不过一个是方法,一个是操作符,而方法可以重写,操作符只有在c++中可以重载,所以并没有重复设计)

2、集合要求里面存放的内容是不能重复的,而java里面在hash表里添加一个项首先根据hashcode再根据equals。为什么要这样的机制,因为这样可以减少equals的调用次数。

要添加的hashcode值与哈希表中已存在的hashcode值不同,则认为项原来不在哈希集合里,于是就添加进去。如果hashcode值相同则再调用equals比较内同是否相同,如果内容也相同则不添加,否则就添加。(这样做的目的是添加项时,可以不用一个个比对集合中的每一个已存在的项,而是直接用hashcode定位到要添加的位置,再判断该位置上是否有重复的项)

例子:hashcode函数用最简单的x%hashtable.length,hash冲突可以采用链表法,或者再散列...

              
012345678910111213

首先集合里为空,我要添加26,26%13=0于是26存到0好单元

26             
012345678910111213

我添加13,13%13=0,结果集合里0号单元有数据,所以长生哈希冲突,于是根据链表法,我放在26上面

13             
26             
012345678910111213

我添加15,15%13=2,于是我就放在2号单元

13             
26 15           
012345678910111213

可以看到,添加集合我完全按照机制2的步骤,我先根据hash函数计算出hashcode,不同则直接添加,相同则再比较内容,内容不同则添加,内容相同则不添加。

 

进入正题:当我们new两个User实例,User aa=new User("小明",20);User bb =new User("小明",20)

他们的hashcode肯定是不一样的(native方法,具体是根据内存地址计算出结果,所以肯定不一样),于是将aa 和bb加入集合中,可以顺利加入,但这两个实例我们自定义了equals方法后认为它们是相等的,不应该加入两个相同的项在集合中,于是我们必须重写hashcode方法,来保证他们hashcode方法也相同(return Object.hash(name,age),这种方案可以办证aa和bb的hashcode相同,从而不会在集合中添加相同的两个项。

另外可以根据上面表格的例子很好记住结论

如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同!!!!; (26和26)

 如果两个对象不同(即用equals比较返回false),那么它们的hashCode值可能相同也可能不同; (26和13)

如果两个对象的hashCode不同,那么他们肯定不同; (显然)

 

说明:hashcode计算方法有很多种,我这举例就用了数据结构中简单的取余,解决hash冲突也有很多种,例子中用了链表发,当然也可以直接往后挪一位比如例子中13就可以放在1号中,若1号也满了就继续完后找空位。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值