Map
Set keySet(): 返回映像中所有關(guān)鍵字的視圖集
Collection values():返回映像中所有值的視圖集
Set entrySet(): 返回Map.Entry對象的視圖集,即映像中的關(guān)鍵字/值對
獲得的對應(yīng)集合可以刪除,但是不可以添加。
Map.Entry接口
Map的entrySet()方法返回一個(gè)實(shí)現(xiàn)Map.Entry接口的對象集合。集合中每個(gè)對象都是底層Map中一個(gè)特定的鍵/值對。
通過這個(gè)集合的迭代器,您可以獲得每一個(gè)條目(唯一獲取方式)的鍵或值并對值進(jìn)行更改。當(dāng)條目通過迭代器返回后,除非是迭代器自身的remove()方法或者迭代器返回的條目的setValue()方法,其余對源Map外部的修改都會導(dǎo)致此條目集變得無效,同時(shí)產(chǎn)生條目行為未定義。
SortedMap接口
SortedMap接口為映像的視圖(子集),包括兩個(gè)端點(diǎn)提供了訪問方法。除了排序是作用于映射的鍵以外,處理SortedMap和處理SortedSet一樣?! ?/span>
添加到SortedMap實(shí)現(xiàn)類的元素必須實(shí)現(xiàn)Comparable接口,否則您必須給它的構(gòu)造函數(shù)提供一個(gè)Comparator接口的實(shí)現(xiàn)。TreeMap類是它的唯一一份實(shí)現(xiàn)。
AbstractMap
HashMap類和TreeMap類
由于TreeMap它底層采用一棵“紅黑樹”來保存集合中的 Entry,這意味這 TreeMap 添加元素、取出元素的性能都比 HashMap 低O(lgN):當(dāng) TreeMap 添加元素時(shí),需要通過循環(huán)找到新增 Entry 的插入位置,因此比較耗性能;當(dāng)從 TreeMap 中取出元素時(shí),需要通過循環(huán)才能找到合適的 Entry,也比較耗性能。但 TreeMap、TreeSet 比 HashMap、HashSet 的優(yōu)勢在于:TreeMap 中的所有 Entry 總是按 key 根據(jù)指定排序規(guī)則保持有序狀態(tài),TreeSet 中所有元素總是根據(jù)指定排序規(guī)則保持有序狀態(tài),對排序二叉樹,若按中序遍歷就可以得到由小到大的有序序列。
《樹和二叉樹》
《各種其他樹》
通過分析 JDK 源代碼研究 TreeMap 紅黑樹算法實(shí)現(xiàn)
TreeMap對鍵按序存放,因此它便有一些擴(kuò)展的方法,比如firstKey(),lastKey()等。TreeMap采用紅-黑樹的二叉搜索樹來保存Map中每一個(gè)Entry,每個(gè)Entery都被當(dāng)成“紅黑樹”的一個(gè)節(jié)點(diǎn)。
public static void main(String[] args)
{ TreeMap<String,Object> treeMap = new TreeMap<String,Object>();
treeMap.put("004", new Integer(40));
treeMap.put("003", new Integer(30));
treeMap.put("001", new Integer(10));
treeMap.put("002", new Integer(20));
}
{001=10, 002=20, 003=30, 004=40}
getEntry()源碼:
final Entry<K,V> getEntry(Object key)
{
// 如果 comparator 不為 null,表明程序采用定制排序
if (comparator != null)
// 調(diào)用 getEntryUsingComparator 方法來取出對應(yīng)的 key
return getEntryUsingComparator(key);
// 如果 key 形參的值為 null,拋出 NullPointerException 異常
if (key == null)
throw new NullPointerException();
// 將 key 強(qiáng)制類型轉(zhuǎn)換為 Comparable 實(shí)例
Comparable<? super K> k = (Comparable<? super K>) key;
// 從樹的根節(jié)點(diǎn)開始
Entry<K,V> p = root;
while (p != null)
{
// 拿 key 與當(dāng)前節(jié)點(diǎn)的 key 進(jìn)行比較
int cmp = k.compareTo(p.key);
// 如果 key 小于當(dāng)前節(jié)點(diǎn)的 key,向“左子樹”搜索
if (cmp < 0)
p = p.left;
// 如果 key 大于當(dāng)前節(jié)點(diǎn)的 key,向“右子樹”搜索
else if (cmp > 0)
p = p.right;
// 不大于、不小于,就是找到了目標(biāo) Entry
else
return p;
}
return null;
}
HashMap和HashTable
LinkedHashMap
擴(kuò)展HashMap,以插入順序?qū)㈥P(guān)鍵字/值對添加進(jìn)鏈接哈希映像中。象LinkedHashSet一樣,LinkedHashMap內(nèi)部也采用雙重鏈接式列表。所以迭代順序也就是插入順序。
WeakHashMap
它使用WeakReference(弱引用)來存放哈希表關(guān)鍵字。使用這種方式時(shí),當(dāng)映射的鍵在 WeakHashMap 的外部不再被引用時(shí),垃圾收集器會將它回收,但它將把到達(dá)該對象的弱引用納入一個(gè)隊(duì)列。WeakHashMap的運(yùn)行將定期檢查該隊(duì)列,以便找出新到達(dá)的弱應(yīng)用。當(dāng)一個(gè)弱引用到達(dá)該隊(duì)列時(shí),就表示關(guān)鍵字不再被任何人使用,并且它已經(jīng)被收集起來。然后WeakHashMap便刪除相關(guān)的映射。
IdentityHashMap
這個(gè)類中,關(guān)鍵字的哈希碼不應(yīng)該由hashCode()方法來計(jì)算,而應(yīng)該由System.identityHashCode方法進(jìn)行計(jì)算(即使已經(jīng)重新定義了hashCode方法)。這是Object.hashCode根據(jù)對象的內(nèi)存地址來計(jì)算哈希碼時(shí)使用的方法。另外,為了對各個(gè)對象進(jìn)行比較,IdentityHashMap將使用==,而不使用equals方法。
換句話說,不同的關(guān)鍵字對象,即使它們的內(nèi)容相同,也被視為不同的對象。IdentityHashMap類可以用于實(shí)現(xiàn)對象拓?fù)浣Y(jié)構(gòu)轉(zhuǎn)換(topology-preserving object graph transformations)(比如實(shí)現(xiàn)對象的串行化或深度拷貝),在進(jìn)行轉(zhuǎn)換時(shí),需要一個(gè)“節(jié)點(diǎn)表”跟蹤那些已經(jīng)處理過的對象的引用。即使碰巧有對象相等,“節(jié)點(diǎn)表”也不應(yīng)視其相等。另一個(gè)應(yīng)用是維護(hù)代理對象。比如,調(diào)試工具希望在程序調(diào)試期間維護(hù)每個(gè)對象的一個(gè)代理對象。
“IdentityHashMap類不是一般意義的Map實(shí)現(xiàn)!它的實(shí)現(xiàn)有意的違背了Map接口要求通過equals方法比較對象的約定。這個(gè)類僅使用在很少發(fā)生的需要強(qiáng)調(diào)等同性語義的情況。”
http://a123159521.javaeye.com/blog/693225 HashMap源碼解析
http://www.javaeye.com/topic/340756 HashSet與HashMap關(guān)系之源碼分析