String.hashCode()源码以及具体计算过程。

String.hashCode()方法通过一个优化的哈希算法计算字符串的哈希值,该算法使用字符数组的每个字符的ASCII值和乘数31。乘数31是一个质数,选择它能降低哈希冲突并提高性能,因为31*i等价于(i<<5)-i,移位操作比乘法更快。文章通过例子展示了字符串hashcode的哈希值计算过程。
摘要由CSDN通过智能技术生成

String.hashCode()源码如下:

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;
        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

从源码中我们可以看出:

  1. String有一个私有变量hash来缓存哈希值,即当该串第一次调用hashCode()方法时,hash默认值为0,继续执行,当字符串长度大于0时计算出一个哈希值赋给hash,之后再调用hashCode()方法时不会重新计算,直接返回hash;
  2. 计算时,使用的是该字符串截成的一个字符数组,用每个字符的ASCII值进行计算,根据注释可以看出哈希计算公式是:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1],n是字符数组的长度,s是字符数组;
  3. 算法中还有一个乘数31,为什么使用31呢?
    hash函数必须选用质数,这是被科学家论证过的hash函数减少冲突的理论;
    1. 如果乘数是偶数,并且乘法溢出的话,信息就会丢失,因为使用偶数相当于位移运算(低位补0);
    2. 31 * i 可以用 (i << 5) - i 来计算,而移位操作的效率高于乘法,所以这是基于性能角度的考虑;
    3. 31是个不大不小的质数,兼顾了性能和冲突率,太小hash冲突概率大,太大过于分散占用存储空间大,所以选择一个不大不小的质数很有必要。

       
      对于字符串"hashcode"的哈希值计算过程如下:
      
          初始化h为0。
          对于字符'h',计算h = 31 * 0 + 'h' = 104。
          对于字符'a',计算h = 31 * 104 + 'a' = 3295。
          对于字符's',计算h = 31 * 3295 + 's' = 102010。
          对于字符'h',计算h = 31 * 102010 + 'h' = 3162931。
          对于字符'c',计算h = 31 * 3162931 + 'c' = 97977461。
          对于字符'o',计算h = 31 * 97977461 + 'o' = 3035438611。
          对于字符'd',计算h = 31 * 3035438611 + 'd' = 94176018441。
          对于字符'e',计算h = 31 * 94176018441 + 'e' = 2922100094061。
          返回最终的哈希值h = 2922100094061。
      
      因此,字符串"hashcode"的hashCode为2922100094061。请注意,hashCode的计算过程可能因为具体的实现而有所不同,上述过程仅为演示目的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值