美文网首页
String 类的方法 -- hashCode()实现的常量系数

String 类的方法 -- hashCode()实现的常量系数

作者: Janice_x | 来源:发表于2018-10-17 19:36 被阅读0次

    先上源码:

    /**

    * Returns a hash code for this string. The hash code for a

    * {@code String} object is computed as

    * <blockquote><pre>* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

    * </pre></blockquote> * using {@code int} arithmetic, where {@code s[i]} is the

    * <i>i</i>th character of the string, {@code n} is the length of

    * the string, and {@code ^} indicates exponentiation.

    * (The hash value of the empty string is zero.)

    *

    * @return  a hash code value for this object.

    */

    public int hashCode() {

    int h =hash;

    if (h ==0 &&value.length >0) {

    char val[] =value;

    for (int i =0; i

    h =31 * h + val[i];

    }

    hash = h;

    }

    return h;

    }

    相信很多朋友跟我一样,在查看String 类中hashCode() 方法具体实现的时候,会有个一疑问,为什么会有个常量系数 31,这个31是什么,怎么来的?有什么具体的含义;然后就各种查;

    我也是简单的查了一下,网上的对这个解读的资料还是蛮多的,很轻松的找到可答案;

    整理了一下,主要是有一下几种原因:

    1、31是素数,素数是什么?素数也是质数,除了1和它本身以外,没有其他因数。所以不能被其他自然数整除

    2、在存储数据计算hash地址的时候,我们希望相同的hash地址越少越好,也就是所谓的“冲突”,因为相同的hash地址的数据越多,生成的hash链表就越长,查找数据遍历的时间就越长,从而降低了查询效率。所以在选择系数的时候,我们希望这个系数越大越好(hash地址越大,冲突的概率越小,查询效率就高),但是相乘最好不要溢出(系数越大,越容易造成数据溢出,溢出的话,会造成数据的丢失)。而 31= 11111【二进制】,只占5bits。

    3、我们都知道,计算机的乘法涉及到移位计算,一个数*2直接将这位数往左移一位即可,31*i = 2^5 * i - i, 相当于 i 向 左移动5位,再减 i,这样就转化成移位和减法结合的计算,比直接相乘的速度更快。也算是对算法的一种优化

    综合以上几个原因,选择了31这个系数。

    相关文章

      网友评论

          本文标题:String 类的方法 -- hashCode()实现的常量系数

          本文链接:https://www.haomeiwen.com/subject/wumrzftx.html