• 为什么在定义hashcode时要使用31这个数呢?


    public int hashCode() {

    int h = hash;
    int len = count;
    if (h == 0 && len > 0) {
    int off = offset;
    char val[] = value;
    for (int i = 0; i < len; i++) {
    h = 31*h + val[off++];
    }
    hash = h;
    }
    return h;
    }

    该函数是我看的函数接口源码,为什么要使用31这个数呢?

    其实上面的实现也可以总结成数数里面下面这样的公式:

    s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]

    原因如下:

    A.31是一个素数,素数作用就是如果我用一个数字来乘以这个素数,那么最终的出来的结果只能被素数本身和被乘数还有1来整除!。(减少冲突)

    B.31可以 由i*31== (i<<5)-1来表示,现在很多虚拟机里面都有做相关优化.(提高算法效率)

    C.选择系数的时候要选择尽量大的系数。因为如果计算出来的hash地址越大,所谓的“冲突”就越少,查找起来效率也会提高。(减少冲突)

    D.并且31只占用5bits,相乘造成数据溢出的概率较小。
     s[i]是string的第i个字符,n是String的长度。那为什么这里用31,而不是其它数呢?《Effective Java》是这样说的:之所以选择31,是因为它是个奇素数,如果乘数是偶数,并且乘法溢出的话,信息就会丢失,因为与2相乘等价于移位运算。使用素数的好处并不是很明显,但是习惯上都使用素数来计算散列结果。31有个很好的特性,就是用移位和减法来代替乘法,可以得到更好的性能:31*i==(i<<5)-i。现在的VM可以自动完成这种优化

  • 相关阅读:
    struct与class的区别
    C#锐利体验第五讲 构造器与析构器(转)
    Sort Table
    WinXP(NTFS分区下)Vista系统文件的删除方法
    关于上海居住证我们不得不说的实情!(转)
    让你眼花缭乱的JS代码~~
    ASP的URL重写技术(IIS的ISAPI)[转]
    JS实现从照片中裁切自已的肖像
    C#锐利体验第二讲 C#语言基础介绍(转)
    装箱和拆箱
  • 原文地址:https://www.cnblogs.com/liuzhuqing/p/7480408.html
Copyright © 2020-2023  润新知