Map 概述:
Map 用于有映射關(guān)系的數(shù)據(jù)却汉,以 key-value 的形式保存秧均。key 和 value 可以是任何類型的數(shù)據(jù)食侮。
1、key:
key 是不允許重復(fù)的目胡,意思就是同一個 Map 對象的任何兩個 key 通過 equals 方法比較后應(yīng)該返回false锯七。如果我們把一個 Map 集合中所有的 key 放在一起看,它們就組成了一個 Set 集合(所有的 key 是沒有順序的誉己,而且 key 是不可以重復(fù)的)眉尸。而且我們可以通過 keySet()方法獲取 Map 集合中由 key 組成的 Set 集合。
Map 和 Set 的關(guān)系是很密切的。如果把 value 當(dāng)成 key 的附屬的話噪猾,僅僅看 key霉祸,我們就可以把 Map 當(dāng)成 Set 了。事實上袱蜡,Map 內(nèi)部封裝了一個內(nèi)部類:Entry丝蹭。由 Entry 來封裝 key-value,而計算 Entry 存儲時只考慮 Entry 封裝的 key坪蚁。其實 Java源碼中奔穿,是先實現(xiàn)了 Map ,然后通過包裝一個所有 value 都為 null 的 Map 來實現(xiàn) Set 集合敏晤。
2贱田、value:
如果我們把 Map 集合中的所有 value 放在一起看,它們又類似于一個 List:value之間可以重復(fù)茵典,每個 value 可以通過索引(key)來查找湘换。我們可以通過索引來取出 value。只不過這個時候索引值不再是整數(shù)统阿,而是任意類型都可以彩倚。
下面的示例展示了 Map 集合的基本功能:
我們通過 put 方法添加鍵值對,添加數(shù)據(jù)的時候扶平,value 值是可以重復(fù)的帆离;添加 key-value 時,如果 key 重復(fù)结澄,新的 value 會覆蓋原來的 value哥谷,而且此方法會返回原來的 value 值。map 集合可以檢查集合中是否存在指定的 key 或者指定的 value麻献;我們可以使用 map 的 keySet 方法獲取 key 的 set 集合们妥,然后遍歷這個 set 集合,循環(huán)取出 value 值勉吻;我們可以根據(jù) key 去刪除這個 key-value 對监婶。
HashMap 和 Hashtable:
HashMap 、Hashtable 是 Map 接口典型的實現(xiàn)類齿桃,不過 Hashtable 出現(xiàn)的比較早惑惶,比 Map 還要早。
不同點:
1短纵、Hashtable 是一個線程安全的類带污,HashMap 是線程不安全的類,所以 HashMap 的性能好一點香到,但如果多個線程操作 Map 集合鱼冀,可以考慮使用 Hashtable报破。
2、Hashtable 不允許使用 null 作為 key 或者 value雷绢,若果存入 null 將會引發(fā) NullPointExecption泛烙;但是 HashMap 可以使用 null 作為 key 或者 value。但是也只能存入一個 key 為 null 的鍵值對翘紊,因為 key 是不可以重復(fù)的蔽氨,可以存入無數(shù)個 value 為 null 的鍵值對。我們看下例子:
我們先后存入兩隊鍵值對都為 null 的元素帆疟,再存入 key 為 one鹉究,value 為 null 的元素,然后打印輸出集合元素內(nèi)容可以看到:只有兩對鍵值對 null-null 和 one-null踪宠。
類似點:
1自赔、我們知道,HashSet 集合存入元素時柳琢,判斷兩個元素是否相等的依據(jù)是: hashCode 方法的返回值是否相同绍妨,兩個對象通過 equals 方法對比返回 true。而HashMap 對于存入的 key 也是相同的依據(jù):hashCode 方法的返回值要相等柬脸,equals 方法返回 true他去。那如何判斷 兩個value 是否相等呢?依據(jù)比較簡單倒堕,只需要兩個對象通過 equals 方法返回 true 即可灾测。我們可以通過下面示例看一下:
上例中,類 F 有一個屬性 count垦巴,如果 count 相等媳搪,則 hashCode 返回值相等,equals 方法返回true骤宣。類 G 重寫 equals 方法秦爆,無論何時都返回 true。測試代碼中憔披,我們查詢 map 中是否存在 value 值為任意類 G 對象的元素鲜结。我們得到的結(jié)果是存在,因為類 G equals 方法返回 true活逆。當(dāng)我們查詢是否含有 count 值為20的 F 對象時,因為count相等拗胜,hashCode 返回值相等蔗候,equals 返回true,所以埂软,得到的結(jié)果也是存在锈遥。不過這里纫事,我們要注意一個問題,HashMap 調(diào)用 containsValue(Object value) 方法時所灸,方法內(nèi)調(diào)用的是傳入?yún)?shù)的 equals 方法丽惶,而 Hashtable 調(diào)用 containsValue 方法時,方法內(nèi)調(diào)用的是 Hashtable 內(nèi) value 對象的 equals 方法爬立。我們看一下兩個類的源碼就清楚了:
2钾唬、與 HashSet 類似,我們盡量不要修改作為 key 值的元素對象侠驯,因為這會出現(xiàn)無法準(zhǔn)確訪問的問題抡秆,我們看下面的例子:
例子中,我們先存入兩對 key-value吟策,然后取出其中一個 key 為 10000 的數(shù)據(jù)并修改成 39723儒士,然后我們刪除 key=39723的數(shù)據(jù),刪除后檩坚,我們發(fā)現(xiàn) map 集合里還存在一條我們之前修改過的數(shù)據(jù)着撩,之后我們執(zhí)行查詢操作后發(fā)現(xiàn),無論查詢 key=10000的數(shù)據(jù)還是 key=39723的數(shù)據(jù)匾委,結(jié)果都是 null拖叙。所以,我們使用過程中盡量不要修改 key 對象剩檀。