在《Effective Java》中寫道:在每個覆蓋了equals方法的類中,都必須覆蓋hashCode方法。可見hashCode方法是非常重要的。編寫hashCode方法要遵循兩點原則:
(a)相等的對象必須擁有相等的散列碼;
(b)不相等的對象的散列碼儘量不要相等。
在一些基本類如Integer、Double、String都已實現了hashCode方法。如果編程時需要將自定義的類型作爲hashMap、hashSet的Key,重載equals的同時,必須要重載hashCode方法。
下面的代碼只重載了equals,沒有重載hashCode。當put的兩個Key爲相等的對象時,它們的散列碼並不相等,因此在HashMap中便產生了兩組鍵值對。
import java.util.*;
public class Main{
public static void main(String[] args) {
class A{
int val1,val2;
public A(int x, int y) {
val1=x;val2=y;
}
/*@Override
public int hashCode() {
return Objects.hash(val1,val2);
}*/
@Override
public boolean equals(Object o) {
if(o instanceof A) { //檢測o是否能轉換成A的一個實例
A a=(A)o; //由於傳入參數是object類,這裏需要向下轉型
return this.val1==a.val1&&this.val2==a.val2;
}
return false;
}
}
Map<A,Integer> m=new HashMap<>();
m.put(new A(1,2),1);
m.put(new A(1,2),2);
for(A a:m.keySet()) { //KeySet return a set view of the keys contained in this map
Integer i=m.get(a);
System.out.println(i);
}
}
}
其中,hashCode可以直接調用Objects類的靜態方法hash,它其實是對Arrays.hashCode的封裝。