java Map使用Object 做為Key的問題


近期在看dnsjava 源碼的時候,不經意間發現一個自己沒有想過的問題:

HashMap 如何使用key去查找對應的value的,這個問題很難用語言描述的清楚,那就使用代碼來進行說明吧!

 

public class test {
    public static void main(String[] args) {
        a aa = new a();
        b bb = new b();
        Map<Object,Object> c = new HashMap<Object,Object>();
        c.put(aa, bb);
        a cc = new a();
        c.get(cc);
System.out.println(bb); System.out.println(c.get(aa)); System.out.println(c.get(cc)); } }
class a { } class b { }

運行結果為:

test.java.hashmap.b@10b30a7

test.java.hashmap.b@10b30a7
null

 

 

為什么使用aa能獲取到value 而 cc就不行呢?aa 和 cc是同一個類的實例啊,如果這樣的話HashMap還怎么根據對象來查找value呢?為什么以前使用String就可以查找value呢?帶着一連串的疑問我們繼續來尋找答案

首先我們來測試下使用String做為Key 看是否真的可以取出對應的value

public class test {

    public static void main(String[] args) {
        Map<Object,Object> c = new HashMap<Object,Object>();
        String aa = new String("abc");
        b bb = new b();
        c.put(aa, bb);
        String cc = new String("abc");
        System.out.println(bb);
        System.out.println(c.get(aa));
        System.out.println(c.get(cc));
    }

}
class b {

}

運行結果為:

test.java.hashmap.b@61de33
test.java.hashmap.b@61de33
test.java.hashmap.b@61de33

使用String的時候運行正常,下面咱們就去看看HashMap的源碼來一探究竟,下面是HashMap get方法的源碼

    public V get(Object key) {
        if (key == null)
            return getForNullKey();
        int hash = hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                return e.value;
        }
        return null;
    }

從源碼中可以看出,主要根據兩個方法來判斷Key是否相同:hashCode 和 equals ,這兩個方法都是在Object中定義的,具體的作用請看http://blog.csdn.net/fenglibing/article/details/8905007

根據上面的分析,要想使用自定義的對象作為key 必須要重寫從Object中繼承過來的hashCode 和 equals。String 中已經對兩個方法進行了重新實現,各位可查看String相關源碼。

public class test {
    public static void main(String[] args) {
        a aa = new a();
        b bb = new b();
        Map<Object,Object> c = new HashMap<Object,Object>();
        c.put(aa, bb);
        a cc = new a();
        c.get(cc);
        System.out.println(bb);
        System.out.println(c.get(aa));
        System.out.println(c.get(cc));
    }
}
class a {
    public int hashCode() {
        return 1;
    }
    public boolean equals(Object obj) {
        return true;
    }
}
class b {
}

運行結果為:

test.java.hashmap.b@14318bb
test.java.hashmap.b@14318bb
test.java.hashmap.b@14318bb

 

 


免責聲明!

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



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