有关hashcode使用31系数问题

String.class类提供的源代码:

    public int hashCode() {
     int h = hash;
     if (h == 0) {
         int off = offset;
         char val[] = value;
         int len = count;

      for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
               }
              hash = h;
         }
        return h;
    }

hashcode()方法解释为数学表达式,即为:h = 31^(n-1)*val[0]+31^(n-2)*val[1]+31^(n-3)*val[2]+......+31^0*val[n-1]

例如:字符串"abcd", h = 31^(3)*a + 31^(2)*b+31^(1)*c+31^(0)*d

为什么会选择31作为系数?计算机的乘法涉及到移位计算。31=32-1,可看做2左移5位减1。

31作为一个素数,计算得到的数据的hash地址可尽量减少重复,使用相同hash地址的数据越少,查找的效率就越高。计算hashcode选择的系数要尽量大,并且计算的结果要在int数据类型的范围内,防止溢出。计算出的hashcode值越大,数据之间的hashcode相同的冲突就会越小,查找效率随之提高。当然,选择31作为系数,不一定最完美的,但一定是非常合理的选择。

posted @ 2016-01-06 09:41  leoJava  阅读(234)  评论(0)    收藏  举报