【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,当然,用其他的数字也没错。

浙公网安备 33010602011771号