You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java String.hashCode()方法推导解析及Cat示例计算疑问解答

解惑Java String.hashCode()中"Cat"的哈希值计算过程

别担心,我来帮你把这个计算过程拆解得明明白白!你的核心问题是记错了字符对应的Unicode(ASCII)值,咱们一步步来:

第一步:确认字符的正确Unicode值

你之前用的37、66、85是完全错误的,正确的ASCII(Unicode的子集)值应该是:

  • 大写字母'C':67
  • 小写字母'a':97
  • 小写字母't':116

你可以通过Java代码快速验证:

System.out.println((int)'C'); // 输出67
System.out.println((int)'a'); // 输出97
System.out.println((int)'t'); // 输出116

第二步:代入公式计算

课本给出的公式是对的:S₀×31^(n-1) + S₁×31^(n-2) + … + S(n-1),对于"Cat"这个长度为3的字符串,n=3,计算过程如下:

  1. 先计算31的幂次:31² = 961,31¹=31,31⁰=1
  2. 代入字符值:
    • 'C' × 31² = 67 × 961 = 64387
    • 'a' × 31 = 97 × 31 = 3007
    • 't' × 1 = 116 × 1 = 116
  3. 求和:64387 + 3007 + 116 = 67510,和课本的结果完全一致!

额外补充:为什么Java选择31作为乘数?

Java里用31不是随便选的,主要有两个原因:

  • 31是质数:质数作为乘数能有效减少不同字符串产生相同哈希值的概率(哈希碰撞)。
  • 计算高效:31可以用位运算快速计算:31 * i = (i << 5) - i,因为2^5=32,32i -i=31i,比直接乘法更快。

关于String.hashCode()的额外细节

在Java的实际实现中,哈希值的计算是迭代进行的,避免直接计算大幂次(防止溢出,但Java的int溢出是允许的,属于设计的一部分),大致逻辑如下:

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;
}

你可以用这个迭代方式再算一遍"Cat":

  • 初始h=0
  • 第一步:h = 31*0 + 67 = 67
  • 第二步:h = 31*67 + 97 = 2077 + 97 = 2174
  • 第三步:h = 31*2174 + 116 = 67394 + 116 = 67510
    结果和之前完全一样!

内容的提问来源于stack exchange,提问作者Jack White

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:01:30