java自定義類型 作為HashMap中的Key值 (Pair 為例)


由於是自定義類型,所以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,這樣只是重載了並不是覆蓋。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM