【Java】为什么要同时重写hashcode和equals

在JDK中对equals(Object obj)和hashCode()这两个方法的定义是:

在Java中任何一个对象都具备equals(Object obj)和hashCode()这两个方法,因为这两个方法是在Object类中定义的。equals(Object obj)用来判断两个对象是否相同,hashCode()用来返回此对象的哈希码值,一个int数,在Object类中,hashCode()的默认实现是把该对象的内部地址转换成一个整数返回。

那么为什么在重写equals方法时一般必须重写hashCode方法呢?

这里就必须提到HashSet与HashMap等散列存储结构了,在这些散列存储结构中,将一个对象放入集合,首先就必须进行哈希码值的判断,如果新放入的对象与集合中任意一个对象的哈希码值相等,就再调用equals方法进行比较,如果还是相等的,则不会放入集合中。

在这个过程中,如果在第一步哈希码值的判断过程中,发现没有重复的哈希码值,则会直接放入集合,并不会进行equals方法的判断,所以如果不重写hashCode()方法,很容易将相同的对象放入集合中。

在开发过程中,除非你能保证后期这个对象不会放在这些散列对象中,否则必须hashCode()和equals(Object obj)同时重写。

在这里提到一个冷知识,为什么在重写hachCode时一般用31进行计算?

在重写hashCode()方法时,为了避免偶然性带来的错误,一般会将一些值乘31,保证每个对象的哈希码值不一样,用31而不是用其他的数字的原因是:

1、31是一个质数,这个数不大也不小

2、这个数好算,2^5-1,向左移动5位,可以通过位移的方式来处理乘法。

综上,使用31可以获得性能上的优化,所以使用31,当然,用其他的数字也没错。

posted @ 2020-08-08 16:13  枫叶藏在眼眸  阅读(145)  评论(0)    收藏  举报