回炉重造之java基础篇:equals() 和 hashCode()

java equals() 和 hashCode()
equals() 判断两对象是否相等,hashCode() 计算对象哈希码
都不是 final 方法,都可被重写

重写equals方法时必须重写hashcode()

Object 的 hashcode()
public native int hashCode();

实际将对象内存地址作哈希码返回,保证不同对象返回值不同

哈希表中起作用

如果对象在 equals() 中使用的信息都没有改变,那么 hashCode() 值始终不变

如果两个对象使用 equals() 方法判断为相等,则 hashCode() 方法也应该相等

如果两个对象使用 equals() 方法判断为不相等,则不要求 hashCode() 也必须不相等;但是开发人员应该认识到,不相等的对象产生不相同的 hashCode 可以提高哈希表的性能

为什么要 hashCode()
插入时通过哈希码直接映射到哈希表中的位置

该位置没有对象,直接插入该位置

该位置有对象, 调 equals() 比较对象是否相等,相等则不需要保存;不相等,加入到链表中 (jdk8 优化为达到链表阀值用红黑树提升性能)

解释了为什么 equals() 相等,则 hashCode() 必须相等

equals() 相等,哈希表中只出现一次;如 hashCode() 不相等,会散列到哈希表不同位置,哈希表中出现了不止一次

String 的 hashCode() 计算公式为:s[0]31^(n-1) + s[1]31^(n-2) + … + s[n-1]

数字 31

质数计算哈希码,它与其他数字相乘之后,计算结果唯一的概率更大,哈希冲突的概率更小

质数越大,哈希冲突的概率越小,但计算速度也越慢;31 是哈希冲突和性能的折中,经验值

JVM 会自动对 31 进行优化:31 * i == (i << 5) - i

分享到: