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

如何合并两个哈希码?如何计算数组等集合的哈希码?

合并哈希码与数组哈希码实现

合并两个哈希码的方法

合并哈希码的核心是用质数加权减少碰撞概率,Java中普遍用31作为权重——它是质数,且31 * hash可等价为(hash << 5) - hash,移位运算比乘法更高效,还能保证哈希值分布均匀。

合并两个哈希码的通用实现:

function combineHash(hash1, hash2) {
    // 用|0确保结果为32位有符号整数,对齐Java的int类型逻辑
    return (hash1 * 31 + hash2) | 0;
}

若想避免乘法,也可以用移位实现等价逻辑:

function combineHash(hash1, hash2) {
    return ((hash1 << 5) - hash1 + hash2) | 0;
}

基于N个哈希码计算集合哈希码(以数组为例)

参考Java的Arrays.hashCode()实现,我们可以遍历数组元素,逐步合并每个元素的哈希码。具体步骤:

  1. 初始化累积结果为1(Java数组哈希的标准初始值)
  2. 遍历数组每个元素:
    • 元素为null时,用0作为其哈希码
    • 否则调用元素的hashCode()方法获取哈希值
  3. 用合并公式更新累积结果
  4. 返回最终的累积哈希码

数组哈希码的具体实现

// 先定义cyrb53函数(来自Stack Overflow)
function cyrb53(str, seed = 0) {
    let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
    for(let i = 0, ch; i < str.length; i++) {
        ch = str.charCodeAt(i);
        h1 = Math.imul(h1 ^ ch, 2654435761);
        h2 = Math.imul(h2 ^ ch, 1597334677);
    }
    h1 = Math.imul(h1 ^ (h1>>>16), 2246822507);
    h1 ^= Math.imul(h2 ^ (h2>>>13), 3266489909);
    h2 = Math.imul(h2 ^ (h2>>>16), 2246822507);
    h2 ^= Math.imul(h1 ^ (h1>>>13), 3266489909);
    return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}

// 已实现的Number、String哈希方法
Number.prototype.hashCode = function() { return this }
String.prototype.hashCode = function() { return cyrb53(this) }

// 数组哈希方法实现
Array.prototype.hashCode = function() {
    let result = 1;
    for (const element of this) {
        const elementHash = element == null ? 0 : element.hashCode();
        // 用Math.imul避免精度丢失,保证32位整数运算逻辑
        result = Math.imul(result, 31) + elementHash;
        // 截断为32位有符号整数,和Java哈希规则对齐
        result |= 0;
    }
    return result;
}

补充说明

  • 使用Math.imul做乘法,避免JavaScript普通乘法的精度丢失,和Java的32位整数运算逻辑保持一致
  • 处理null元素的情况,符合Java的哈希规范
  • 最终结果用|0截断为32位有符号整数,模拟Java的int类型哈希码

内容的提问来源于stack exchange,提问作者Alex Craft

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 06:06:29