
java-hashcode-650x369.jpeg
Java超類java.lang.Object定義了兩個(gè)重要方法。
public boolean equals(Object obj)
public int hashCode()
在文章中嗎,我首先會(huì)展示一個(gè)常見錯(cuò)誤的例子,然后解釋equals()和hashCode()工作的聯(lián)系。
1. 一個(gè)常見錯(cuò)誤
下面的例子展示了常見的錯(cuò)誤:
import java.util.HashMap;
public class Apple {
private String color;
public Apple(String color) {
this.color = color;
}
public boolean equals(Object obj) {
if(obj==null) return false;
if (!(obj instanceof Apple))
return false;
if (obj == this)
return true;
return this.color.equals(((Apple) obj).color);
}
public static void main(String[] args) {
Apple a1 = new Apple("green");
Apple a2 = new Apple("red");
//hashMap stores apple type and its quantity
HashMap<Apple, Integer> m = new HashMap<Apple, Integer>();
m.put(a1, 10);
m.put(a2, 20);
System.out.println(m.get(new Apple("green")));
}
}
在main方法中,創(chuàng)建了一個(gè)紅蘋果和綠蘋果,并放到了HashMap中。然而,當(dāng)要求從HashMap中得到綠蘋果時(shí),綠蘋果卻找不到了。上面的代碼執(zhí)行結(jié)果將會(huì)打印null。
我們?cè)赿ebugger時(shí),檢查HashMap后,可以肯定綠蘋果已經(jīng)被存儲(chǔ)到了hashMap。

hashCode-and-equals-contract-600x268.png
問(wèn)題的原因是什么呢?
2. 問(wèn)題由hashCode()產(chǎn)生
因?yàn)闆](méi)有重寫"hashCode()"方法導(dǎo)致了上面的問(wèn)題。equals()和hashCode()之間的聯(lián)系如下:
- 如果兩個(gè)對(duì)象是相等的,那么他們的hash code值必須相等。
- 如果兩個(gè)對(duì)象的hash code相等,這兩個(gè)對(duì)象可能相等也可能不相等。
Map背后的思想是為了能夠比線性搜索更快的查找到一個(gè)對(duì)象。
問(wèn)題的解決辦法是往Apple類中添加hashCode方法。
public int hashCode(){
return this.color.hashCode();
}