HashCodeBuilder生成重复哈希码:不同数值组哈希结果相同求助
哈希码碰撞问题分析与解决
你遇到的是哈希碰撞:不同输入生成相同哈希码的情况,这是哈希算法的固有特性,并非bug。
原因解析
哈希码的核心是将任意多的输入映射到固定长度的整数(Java中是32位int,仅2^32种可能),输入的可能性远大于这个数量,所以碰撞必然会发生。
以你用的HashCodeBuilder为例,它的计算逻辑是链式加权求和(简化公式):
hash = 初始值 * 乘数 + 第一个值 hash = 上一步结果 * 乘数 + 第二个值 hash = 上一步结果 * 乘数 + 第三个值
你使用的初始值17、乘数37,两组数值经过计算后,刚好在32位int的溢出规则下得到了相同结果——Java中整数溢出会自动执行模2^32的运算,最终导致哈希码一致。
解决方法
更换哈希参数
换一组不同的质数作为初始值和乘数,比如31和101,能大幅降低这两组值的碰撞概率:new HashCodeBuilder(31, 101).append(8079).append(7540).append(15774).toHashCode(); new HashCodeBuilder(31, 101).append(8099).append(6801).append(15737).toHashCode();增加特征字段
如果你的对象还有其他属性,把它们也加入append调用中,增加输入的唯一性,减少碰撞可能。避免仅依赖哈希码判断相等
哈希码的作用是快速分组(比如HashMap的键),判断两个对象是否相等必须配合equals方法,不能仅靠哈希码一致就认定对象相同——这是Java规范的要求。使用其他哈希方案
如果业务需要更低的碰撞概率,可以用Java 8的Objects.hash(),或者自定义更复杂的哈希逻辑;如果要求绝对唯一,不要用哈希码,改用UUID或业务唯一标识。
内容的提问来源于stack exchange,提问作者HieuBui
相关产品推荐
相关产品推荐

