Java中hashcode核心算法

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作为乘数

发布了132 篇原创文章 · 获赞 11 · 访问量 8700

猜你喜欢

转载自blog.csdn.net/xuanyuanjiaqi/article/details/105258181