由於是自定義類型,所以HashMap中的equals()方法和hashCode()方法都需要自定義覆蓋。
不然內容相同的對象對應的hashCode會不同,無法發揮算法的正常功能,覆蓋equals方法,應該就相當於c++重載==運算符來保證能判斷是否相等。只不過java沒有自定義重載運算符這個功能的,需要進行方法覆蓋。
equals的方法原型是 boolean equals(Object o);注意括號內,因為是繼承自Object類,覆蓋的是超類的方法。hashCode的方法原型就是int hashCode();
先看一段代碼:
import java.util.*; class Pair<V,K>{ V first; K second; public Pair() {first = null;second = null;} public Pair(V f,K s){ first = f; second = s; } // public boolean equals(Object o) { // if(!(o instanceof Pair)) // { // return false; // } // Pair<V,K> pn = (Pair<V,K>)o; // return pn.first.equals(first) && pn.second.equals(second); // } // public int hashCode() { // return first.hashCode() + second.hashCode(); // } } public class Main { public static void main(String[] args) { Pair<String,String> p = new Pair<>("a","b"); Pair<String,String> q = new Pair<>("a","b"); System.out.println(p.equals(q)); System.out.println(p.hashCode() + " " + q.hashCode()); Map<Pair<String,String>,Integer> map = new HashMap(); map.put(p, 1); System.out.println(map.containsKey(q)); map.put(q, 2); for(Pair<String,String> key : map.keySet()) { System.out.println(map.get(key)); } } }
這段代碼把覆蓋重寫的兩個方法給注釋掉了,然后判斷了值相同的兩個Pair對象p和q是否相等,並輸出了他們的hashCode,同時把p放進建立的HashMap中,用q來判斷p是否存在,再把q放入,並遍歷map的values。答案是:
false
2018699554 1311053135
false
1
2
然后:
import java.util.*; class Pair<V,K>{ V first; K second; public Pair() {first = null;second = null;} public Pair(V f,K s){ first = f; second = s; } public boolean equals(Object o) { if(!(o instanceof Pair)) { return false; } Pair<V,K> pn = (Pair<V,K>)o; return pn.first.equals(first) && pn.second.equals(second); } public int hashCode() { return first.hashCode() + second.hashCode(); } } public class Main { public static void main(String[] args) { Pair<String,String> p = new Pair<>("a","b"); Pair<String,String> q = new Pair<>("a","b"); System.out.println(p.equals(q)); System.out.println(p.hashCode() + " " + q.hashCode()); Map<Pair<String,String>,Integer> map = new HashMap(); map.put(p, 1); System.out.println(map.containsKey(q)); map.put(q, 2); for(Pair<String,String> key : map.keySet()) { System.out.println(map.get(key)); } } }
然后把注釋去掉之后的結果是:
true
195 195
true
2
雖然說這里的hashCode重寫的沒有什么道理,但是至少值相同的兩個對象他們的hashCode是相同的,這樣在HashMap中第一關判斷hashCode是否相同就過了,接着再遍歷判斷是否有值相同的元素,可以判斷是否含有某個鍵值,並更新鍵值的value等等。
而且要注意equals的覆蓋,參數列表不可以因為是對於Pair對象的判斷就改成Pair p,這樣只是重載了並不是覆蓋。