# Java中 hashCode() 方法如何使用
## 1. 什么是hashCode()
`hashCode()`是Java中`Object`類定義的一個原生方法,返回對象的整數哈希值。這個方法的主要作用是為哈希表數據結構(如`HashMap`、`HashSet`等)提供支持。
```java
public native int hashCode();
根據Java官方文檔,hashCode()必須遵守以下約定:
equals()
比較相等,它們的hashCode必須相同哈希表通過hashCode將元素分布到不同的”桶”中,使得查找操作的時間復雜度接近O(1)。
// HashMap的getNode方法片段(JDK 17)
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
先比較hashCode可以快速排除不相等的對象,避免昂貴的equals()
調用。
equals()
比較的字段都應參與hashCode計算Java 7引入的便捷方法:
@Override
public int hashCode() {
return Objects.hash(name, age, address);
}
處理數組類型字段:
@Override
public int hashCode() {
return 31 * name.hashCode() + Arrays.hashCode(scores);
}
public class Employee {
private String name;
private int age;
private Department dept;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((dept == null) ? 0 : dept.hashCode());
return result;
}
}
Joshua Bloch在《Effective Java》中提出的方案:
@Override
public int hashCode() {
int result = 17;
result = 31 * result + field1.hashCode();
result = 31 * result + field2.hashCode();
result = 31 * result + (int)(field3 ^ (field3 >>> 32));
return result;
}
使用@EqualsAndHashCode
注解:
@EqualsAndHashCode
public class Product {
private String id;
private String name;
private BigDecimal price;
}
private volatile int hashCode; // 延遲初始化
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = Objects.hash(field1, field2);
}
return hashCode;
}
錯誤示例:
// equals比較name但hashCode使用全部字段
@Override
public boolean equals(Object o) {
return this.name.equals(((Student)o).name);
}
@Override
public int hashCode() {
return Objects.hash(name, age); // 違反契約
}
Set<Employee> set = new HashSet<>();
Employee emp = new Employee("John");
set.add(emp);
emp.setName("Peter"); // 修改后hashCode改變
System.out.println(set.contains(emp)); // 可能返回false
public class Manager extends Employee {
private List<Employee> subordinates;
@Override
public int hashCode() {
return 31 * super.hashCode() + subordinates.hashCode();
}
}
枚舉已提供合適的hashCode實現,通常不需要重寫:
public enum Status {
ACTIVE, INACTIVE, PENDING;
// 自動使用ordinal()作為hashCode
}
public class CaseInsensitiveString {
private String s;
@Override
public int hashCode() {
return s.toLowerCase().hashCode();
}
}
@Test
public void testHashCodeContract() {
Person p1 = new Person("Alice", 30);
Person p2 = new Person("Alice", 30);
assertEquals(p1.hashCode(), p2.hashCode());
assertNotEquals(p1.hashCode(), new Person("Bob", 30).hashCode());
}
Map<Integer, Integer> hashDistribution = new HashMap<>();
for (int i = 0; i < 10000; i++) {
int hash = new MyObject(i).hashCode();
hashDistribution.merge(hash, 1, Integer::sum);
}
// 分析沖突率
正確實現hashCode()是編寫高質量Java代碼的關鍵技能。通過理解哈希原理、遵循實現規范并結合實際場景選擇適當策略,可以確保你的類在哈希集合中表現良好。記?。汉玫膆ashCode實現應該平衡分布性、一致性和性能三個維度。
提示:在Java 14+中,可以考慮使用record類型,它會自動生成符合規范的equals()和hashCode()方法。
> public record Point(int x, int y) {} > ```
這篇文章共計約2000字,涵蓋了hashCode()的核心概念、實現方法、注意事項和最佳實踐,采用Markdown格式并包含代碼示例??筛鶕枰{整具體細節或補充更多示例。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。