java.lang.Object類中有兩個非常重要的方法:
public boolean equals(Object obj)
public int hashCode()
了解這兩個方法非常的重要,尤其是将使用者自定義的對象添加到Map中的時候。有時候就算是久經沙場的老程式員也弄不清楚該如何正确使用它們。這篇文章中,我将用一個例子讓大家看看大家經常會犯的錯誤,然後解釋equals()和hashCode()的正确的使用方法。

1. 常見錯誤
常見的錯誤如下:
import java.util.HashMap;
public class Apple {
private String color;
public Apple(String color) {
this.color = color;
}
public boolean equals(Object obj) {
if (!(obj instanceof Apple))
return false;
if (obj == this)
return true;
return this.color == ((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 m = new HashMap();
m.put(a1, 10);
m.put(a2, 20);
System.out.println(m.get(new Apple("green")));
}
這個例子中,一個“綠蘋果”的對象成功添加到hashMap中了,但是當我們要取出這個“綠蘋果”的時候,卻得不到這個對象,程式傳回null。我們使用調試器卻發現在hashMap中已經存儲了這個對象。
2. hashCode()引起的問題
這個問題是因為”hashCode()”方法沒有被重寫。Java中equals()和hashCode()有一個契約:
- 如果兩個對象相等的話,它們的hash code必須相等;
- 但如果兩個對象的hash code相等的話,這兩個對象不一定相等。
Map的結構能夠快速找到一個對象,而不是進行較慢的線性查找。使用hash過的鍵來定位對象分兩步。Map可以看作是數組的數組。第一個數組的索引就是對鍵采用hashCode()計算出來的值,再在這個位置上查找第二個數組,使用鍵的equals()方法來進行線性查找,直到找到要找的對象。
Object類中的hashCode()對于不同的對象傳回不同的整數,是以上面的例子中,不同的對象(即使相同的類型)也傳回不同的hash值。
Hash碼就像是一個存儲空間的序列,不同的東西放在不同的存儲空間中。将不同的東西整理放在不同的空間中(而不是堆積在一個空間中)更高效。是以能夠均勻的分散hash碼是再好不過了。
上面錯誤的解決方法就是在類中增加hashCode方法。這裡我僅僅使用顔色的長度來計算hash碼。
public int hashCode(){
return this.color.length();