hashcode的作用_问:重写equals不重写hashCode会怎样?

f74854293f73d6cb2a8bfe750cba7a91.png

在java中,equals和hashCode方法是Object类的方法,因此,所有用户编写的类都默认拥有这两个方法。

equals方法的作用

根据equals的英文翻译可以看出,这个方法的作用主要是用于比较两个对象是否相等。

在Object类中,equals方法默认使用“==”号来对两个对象进行判断,而在java中,“==”号用在两个对象身上时,比较的是两个对象的地址值,这就意味着当两个对象不是同一个时(地址值不一致就不是同一个对象),就返回为false。

这种判断方式本质上没错,但是不太符合实际需求,就好比在两个不同的超市里面都有矿泉水,但是因为地址值不同,在使用equals做判断时,这两个超市的矿泉水就会返回为false;因此在实际开发中我们往往需要重写Object的equals方法。

hashCode方法的作用

未重写hashCode方法时,它的作用主要是根据当前对象返回一个整型的hash值,不同对象调用hashCode返回的值往往是不一样的。

在java底层集合框架中,为了提高查询效率,往往使用hashCode方法来确定元素的保存位置。

重写equals不重写hashCode会怎样?

以下Sudent类只重写了,Object的equals方法,没有重写hashCode方法

8c84149f610774e1a75384a481cf5d63.png

测试一下:

6c409aa6067db33d1b8dbb34de55fce9.png

测试结果:

2f13367f6bd39648b388b175b19133dd.png

按照我们的常规理解,只要两个学生对象的id和name是一样的,我们就可以认为这两个学生对象指的是同一个人,因此重写了equals方法,让Student对象只要name和id相同就返回true,而且并没有重写hashCode方法。

在测试中,新建了两个Student对象,并且让他们的id和name完全一样,在调用equals方法时,返回为true,说明这两个对象时相等的。但是由于没有重写hashCode方法,所以这两个对象调用的hashCode还是Object类那里的hashCode方法,并且他们的值并不相等。

由此可以得出结论:重写了equals方法,不重写hashCode方法时,可能会出现equals方法返回为true,而hashCode方法却返回不同的结果。

那么这样会有什么影响呢?

在java底层的集合框架中(如HashMap,HashSet等),为了提高查询的效率,在确定某个对象的存储位置时,往往需要通过调用对象的hashCode方法来实现。

例如在上例中,我们把新建出来的两个Student对象放入HashSet集合中:

b881fc922dccedd351bbe6f7c74c85f0.png

按照我们主观理解,这两个对象equals为true,那么HashSet应该主动帮我们去重,最终的HashSet中应该只保留1个对象,即最终输出的HashSet的size为1,但是我们得到的结果却是2:

35d732e17d6cefd50e88e7ef0b76432d.png

之所以会产生这种结果,是因为HashSet的底层其实时数组结构,当需要把一个对象放进去时,会先调用这个对象的hashCode方法,并对返回的结果进行处理,最终得出该对象在HashSet中的具体位置。

由于Student没有重写hashCode方法,所以即使equals判断为true,但是他们保存的位置在底层数组上时不一样的,不会触发HashSet的去重功能,而对于程序员来说,两个相同的对象却会在HashSet中出现多次。

我只是一名菜菜的小码农,如有写得不对的地方,欢迎指正。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值