为什么覆盖equals()方法的时候,必须要覆盖hashCode()方法
注:JDK版本:1.8.0_251
首先,我们来看一下在Object类中,这两个方法是是干嘛的,现贴出代码:
在Object类中, equals方法进行相等比较,是用 == 号对两个对象进行比较。我们知道,在Java中,==比较,如果不是基本数据类型的话,其实比较的是两个对象的内存地址,我们再看看Object类的hashCode()方法:
这个方法呢,它是一个native方法,这个方法会返回当前对象的哈希散列码。
OK,现在打完了Object类的铺垫,我们再来看看HashMap的containsKey()方法的源码:
这个hash方法,是HashMap用来定位key所命中的bucket的位置。
比如说,我们定义如下一个User类:
现在我们来创建两个User对象,这两个User对象的每一个字段都完全一样,我们要把User对象当作HashMap中的key进行存储的话,那么我们看看它们的hashCode()方法的执行结果是否一样?
显然,它们的hashCode是不一样的,接下来,那么将该对应作为HashMap的key,就会有问题了。因为我们希望这两个对象命中同一个bucket,但事实上,这两个对象因为hashcode的不一样,而会命中不一样的bucket。我们现在覆盖一下User类的equals方法和hashCode方法:
覆盖了这两个方法之后,我们再执行上面的test代码,我们再看看效果:
这个时候,他们的hascode也是一样的了。
那有的人可能会说了,那我只覆盖hashcode方法,不覆盖equals方法,它不行吗???好吧,那我们来看看HashMap的containsValue()方法的代码:
前端我们提及过,containsValue方法调用的是Object.equals()方法,如果我们不去覆盖它的话,它只会拿对象的地址进行比较,像上面User类这样的需求,所有字段值完全相同的User对象,也就断然不可能相等了。。。
因此,我们在对一个类的equals方法进行覆盖的时候,通常情况下,我们会同时覆盖equals方法和hashCode()方法。