![f74854293f73d6cb2a8bfe750cba7a91.png](https://i-blog.csdnimg.cn/blog_migrate/8386b7dea8403e8d1b39f6efd180804a.jpeg)
在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](https://i-blog.csdnimg.cn/blog_migrate/7b54862cd1466dd3995084b9a8c1cf6b.jpeg)
测试一下:
![6c409aa6067db33d1b8dbb34de55fce9.png](https://i-blog.csdnimg.cn/blog_migrate/e6e7e2a2c63d233918d945bef0297cf2.jpeg)
测试结果:
![2f13367f6bd39648b388b175b19133dd.png](https://i-blog.csdnimg.cn/blog_migrate/57aa087448c14d122b3e4770fd8f5ec5.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](https://i-blog.csdnimg.cn/blog_migrate/1eea2101da2bacbbc0002a5571db6e6b.png)
按照我们主观理解,这两个对象equals为true,那么HashSet应该主动帮我们去重,最终的HashSet中应该只保留1个对象,即最终输出的HashSet的size为1,但是我们得到的结果却是2:
![35d732e17d6cefd50e88e7ef0b76432d.png](https://i-blog.csdnimg.cn/blog_migrate/af02a63965ccfa49fc51bfc1f987ea5b.png)
之所以会产生这种结果,是因为HashSet的底层其实时数组结构,当需要把一个对象放进去时,会先调用这个对象的hashCode方法,并对返回的结果进行处理,最终得出该对象在HashSet中的具体位置。
由于Student没有重写hashCode方法,所以即使equals判断为true,但是他们保存的位置在底层数组上时不一样的,不会触发HashSet的去重功能,而对于程序员来说,两个相同的对象却会在HashSet中出现多次。
我只是一名菜菜的小码农,如有写得不对的地方,欢迎指正。