<p>Objects.hash 本质是基于31的线性混合算法逐个计算各参数哈希值,等价于 result = 31 * result + Objects.hashCode(a) 的迭代过程,支持 null 安全且顺序敏感。</p>

Objects.hash 本质是把多个参数依次传入,内部用一个固定算法逐个混合计算,不是简单拼接字符串再哈希。
核心原理:基于 31 的线性混合
它等价于手动写:
result = 1;result = 31 * result + Objects.hashCode(a);
result = 31 * result + Objects.hashCode(b);
result = 31 * result + Objects.hashCode(c);
...
这个过程对 null 安全(Objects.hashCode(null) 返回 0),且顺序敏感 —— Objects.hash("a", "b") 和 Objects.hash("b", "a") 结果不同。
正确组合多个属性的写法
- 直接列出所有参与哈希的字段,类型不限(基本类型会自动装箱,对象自动调用
Objects.hashCode) - 字段顺序必须和
equals中比较顺序一致,否则违反哈希契约 - 忽略不参与相等性判断的字段(比如临时计算值、缓存字段)
- 示例:
Objects.hash(id, name, age, isActive)
常见误区提醒
- 不要先拼成字符串再哈希(如
(id + name).hashCode())—— 效率低、易冲突、null 处理麻烦 - 不要用
Arrays.hashCode(new Object[]{...})替代 —— 多一层数组对象开销,语义也不如Objects.hash清晰 - 避免在 hash 计算中调用可能抛异常或有副作用的方法(比如未初始化的懒加载字段)
配合 equals 使用才真正有效
哈希只是辅助,必须和 equals 保持逻辑一致:
立即学习“Java免费学习笔记(深入)”;
- 如果
equals比较了id和name,那hashCode就必须包含这两个字段 - 如果某个字段在
equals中被忽略(例如日志时间戳),它就不该出现在Objects.hash参数里 - IDE 自动生成的
hashCode方法通常就调用Objects.hash(...),只要字段勾选正确就没问题


















