正確實現 hashCode() 是 Java 開發中的基本功,直接影響 HashMap、HashSet 等集合的性能與正確性。本文基於《Effective Java》經典規範,總結出一套通用、高質量的 hashCode() 實現模式,並提供完整代碼示例。
int result = 17;(質數減少碰撞)result = 31 * result + fieldHash;(31 為質數,可優化為位運算)| 類型 | 計算方式 |
|---|---|
| boolean | (f ? 1 : 0) |
| byte/char/short/int | (int) f |
| long | (int)(f ^ (f >>> 32)) |
| float | Float.floatToIntBits(f) |
| double | Double.doubleToLongBits(f) 轉 long 後按 long 處理 |
| 對象引用 | 遞歸調用 hashCode();null 返回 0 |
| 數組 | 各元素視為獨立字段處理;JDK 1.5+ 使用 Arrays.hashCode() |
public static int hashCode(long a[]) {
if (a == null) return 0;
int result = 1;
for (long element : a) {
int elementHash = (int)(element ^ (element >>> 32));
result = 31 * result + elementHash;
}
return result;
}
package com.example.domain;
import java.util.Arrays;
public class Person {
private int age;
private String name;
private char sex;
private String[] hobbies;
public Person(int age, char sex, String name, String[] hobbies) {
this.age = age;
this.sex = sex;
this.name = name;
this.hobbies = hobbies;
}
// Getter/Setter 省略...
@Override
public int hashCode() {
int result = 1;
result = 31 * result + age;
result = 31 * result + sex;
result = 31 * result + (name == null ? 0 : name.hashCode());
if (hobbies != null) {
for (String hobby : hobbies) {
result = 31 * result + (hobby == null ? 0 : hobby.hashCode());
}
}
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person other = (Person) obj;
return age == other.age
&& sex == other.sex
&& (name == null ? other.name == null : name.equals(other.name))
&& Arrays.equals(hobbies, other.hobbies);
}
}
Objects.hash() (JDK 7+)、Arrays.hashCode() 簡化實現@Override
public int hashCode() {
return Objects.hash(age, sex, name, Arrays.hashCode(hobbies));
}
優質的 hashCode() 實現遵循:「質數種子 + 質數乘子 + 全字段覆蓋 + 空值安全 + 委託標準庫」。掌握此模式,配合 IDE 自動生成或 Lombok @EqualsAndHashCode,即可確保集合操作的正確性與高性能。