hashcode 与 equal 方法的关系
-
从规则的角度看
- 如果两个对象相同, equals方法一定返回true,并且这两个对象的HashCode一定相同;
- 两个对象的HashCode相同,并不一定表示两个对象就相同,即equals()不一定为true,只能说明这两个对象在一个散列存储结构中。
- 两个对象的HashCode不相同,这两个对象一定不相同,equals()一定不为true
-
从功能的角度看
- equals方法用于判定两个对象是否相同
- hashcode用于快速查找对象位置(通过取模运算)
核心源码
以下为String对象的HashCode方法
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) { //如果hash值首次运算
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];//核心算法,考虑在int大小的空间中散列相对均匀
}
hash = h;
}
return h;
}
static final int hash(Object key) {
int h;
//高16位和低16位做异或运算,目的是散列更均匀
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
代码通过循环 h = 31 * h + val[i] 公式将一个String对象中所有的字符做为参数串在一起做了一个散列运算。
该散列运算的目的只有一个,在整形的数值区间 [-2147483648, 2147483647]上,算出来的值足够分散,值相同的碰撞越少越好。(区间大小为 2^32)
好了hashcode的算法核心思想已经讲清楚了,至于为什么公式中用的乘数是31,如下文章讲的非常透彻。
https://blog.csdn.net/zhujohnle/article/details/100538706 详细探讨HashCode算法为什么采用31作为乘数