參考文獻(xiàn):《Java瘋狂講義》(第三版)
Map集合
Map用于保存具有映射關(guān)系的數(shù)據(jù)糜芳,(key(不允許重復(fù))惕橙,value)
知識(shí)點(diǎn):
Set與Map關(guān)系非常密切,雖然Map中放的元素是Key-Value對(duì),Set集合中放的元素是單個(gè)對(duì)象,但如果把Key-Value對(duì)中的value當(dāng)成是key的附庸:key在哪里字币,value就在哪里。
事實(shí)上共缕,May提供了一個(gè)Entry內(nèi)部類來封裝key-value洗出,計(jì)算Entry存儲(chǔ)時(shí)則值考慮Entry封裝的key。從Java源碼來看Java是先實(shí)現(xiàn)了Map骄呼,然后通過包裝一個(gè)所有的value都為null的Map就實(shí)現(xiàn)了Set集合共苛。
Hashtable與HashMap兩個(gè)典型區(qū)別:
1、Hashtable是一個(gè)線程安全的Map實(shí)現(xiàn)蜓萄,但HashMap是一個(gè)線程不安全的實(shí)現(xiàn)隅茎,所以HashMap比Hashtable的性能高一點(diǎn);但如果有多個(gè)線程訪問一個(gè)Map對(duì)象時(shí)嫉沽,使用Hashtable實(shí)現(xiàn)類會(huì)更好辟犀。
2、Hashtable不允許使用null作為key和value绸硕,如果視圖把null值放進(jìn)Hashtable中堂竟,將會(huì)引發(fā)NullPointerException異常:但HashMao可以使用null作為key或value。
知識(shí)點(diǎn):
從Hashtable的類名上就可以看出它是一個(gè)古老的類玻佩,它的命名甚至沒有遵守Java的命名規(guī)范:每個(gè)單詞的首字母都應(yīng)該大寫出嘹。也許當(dāng)初開發(fā)Hashtable的工程師也沒有注意,后來大量的Java程序使用了Hashtable類咬崔,所以這個(gè)類名也就不能改為HashTable了税稼,否則大量程序需要重寫。與Vector類似的是垮斯,盡量少用Hashtable實(shí)現(xiàn)類郎仆,即使需要?jiǎng)?chuàng)建線程安全的Map實(shí)現(xiàn)類,也無須使用Hashtable實(shí)行類兜蠕,可以通過后面介紹的Collections工具類把HashMap編程線程安全的扰肌。
知識(shí)點(diǎn):
為了成功在HashMap、Hashtable中存儲(chǔ)熊杨、獲取對(duì)象曙旭,用作key的對(duì)象必須實(shí)現(xiàn)hashCode()方法和equals()方法。
知識(shí)點(diǎn):
當(dāng)使用自定義類作為HashMap晶府、Hashtable的key時(shí)桂躏,如果重寫該類的equals(Object obj)和hashCode()方法,則應(yīng)該保證兩個(gè)方法的判斷標(biāo)準(zhǔn)一致——當(dāng)兩個(gè)key通過equals()方法比較返回true時(shí)郊霎,兩個(gè)key的hashCode()返回值也應(yīng)該相同沼头。
因?yàn)镠ashMap、Hashtable保存key的方式與HashSet保存集合元素的方式完全相同,所以HashMap进倍、Hashtable對(duì)key的要求與HashSet對(duì)集合元素的要求完全相同土至。
知識(shí)點(diǎn):
與HashSet類似的是,盡量不要使用可變對(duì)象作為HashMap猾昆、Hashtable的key陶因,如果確實(shí)需要使用可變對(duì)象作為HashMap、Hashtable的key垂蜗,則盡量不要在程序中修改key的可變對(duì)象楷扬。
LinkedHashMap實(shí)現(xiàn)類
使用雙向鏈表維護(hù)key-value的次序(其實(shí)只要考慮key的次序),該鏈表負(fù)責(zé)維護(hù)Map的迭代順序贴见,迭代順序與key-value對(duì)的插入順序保持一致烘苹。
Properties類
Properties類是Hashtable的子類。
該對(duì)象在處理屬性文件時(shí)特別方便(Windows操作平臺(tái)的ini文件就是一種屬性文件)片部。
Properties類可以把Map對(duì)象和屬性文件關(guān)聯(lián)起來镣衡,從而把Map對(duì)象中的key-value對(duì)寫入屬性文件中,也可以把屬性文件“屬性名=屬性值”加載到Map對(duì)象中档悠。由于屬性文件里的屬性名廊鸥、屬性值都是字符串,所以Properties里的key辖所、value都是字符串惰说。
SortedMap接口和TreeMap實(shí)現(xiàn)類
SortedMap接口也有一個(gè)TreeMap實(shí)現(xiàn)類,類似SortedSet缘回、TreeSet吆视;
注意:
再次強(qiáng)調(diào):Set和Map的關(guān)系十分密切,Java源碼就是先實(shí)現(xiàn)了HashMap切诀、TreeMap等集合揩环,然后通過包裝一個(gè)所有的value都為null的Map集合實(shí)現(xiàn)了Set集合類搔弄。
WeakHashMap實(shí)現(xiàn)類:
WeakHashMap與HashMap的用法基本相似幅虑。
區(qū)別在于,HashMap的key保留了對(duì)實(shí)際對(duì)象的強(qiáng)引用顾犹,這就意味著只要該HashMap對(duì)象不被銷毀倒庵,該HashMap的所有key所引用的對(duì)象就不會(huì)被垃圾回收,HashMap也不會(huì)自動(dòng)刪除這些key所對(duì)應(yīng)的key-value對(duì)炫刷;但WeakHashMap的key只保留了對(duì)實(shí)際對(duì)象的弱引用擎宝,這意味著如果WeakHashMap對(duì)象的key所引用的對(duì)象沒有被其他強(qiáng)引用變量所引用,則這些key所引用的對(duì)象可能被垃圾回收浑玛,WeakHashMap也可能自動(dòng)刪除這些key所對(duì)應(yīng)的key-value對(duì)绍申。
WeakHashMap的每個(gè)key對(duì)象只持有對(duì)實(shí)際對(duì)象的弱引用,因此當(dāng)垃圾回收了該key所對(duì)應(yīng)的實(shí)際對(duì)象之后,WeakHashMap會(huì)自動(dòng)刪除該key對(duì)應(yīng)的key-value對(duì)极阅。
IdentityHashMap實(shí)現(xiàn)類
這個(gè)Map實(shí)現(xiàn)類的實(shí)現(xiàn)機(jī)制與HashMap基本相似胃碾,但它在處理兩個(gè)key相等時(shí)比較獨(dú)特:在IdentityHashMap中,當(dāng)且僅當(dāng)兩個(gè)key嚴(yán)格相等(key1==key2)時(shí)筋搏,IdentityHashMap才認(rèn)為兩個(gè)key相等
知識(shí)點(diǎn):
IdentityHashMap是一個(gè)特殊的實(shí)現(xiàn)類仆百,此類實(shí)現(xiàn)Map接口時(shí),它有意違反Map的通常規(guī)范:要求兩個(gè)key嚴(yán)格相等時(shí)才認(rèn)為兩個(gè)key相等奔脐。
EnumMap實(shí)現(xiàn)類
EnumMap是一個(gè)與枚舉類一起使用的Map實(shí)現(xiàn)俄周,EnumMap中的所有key必須是單個(gè)枚舉類的枚舉值。創(chuàng)建EnumMap時(shí)必須顯式或隱式地指定它對(duì)應(yīng)的枚舉類髓迎。
特征:
1峦朗、EnumMap在內(nèi)部以數(shù)組形式保存,所以這種實(shí)現(xiàn)形式非常緊湊排龄、高效甚垦。
2、EnumMap根據(jù)key的自然順序來維護(hù)key-value對(duì)的順序涣雕。
3艰亮、EnumMap不允許使用null作為key,允許使用null作為value
各Map實(shí)現(xiàn)類性能分析:
HashMap和Hashtable的實(shí)現(xiàn)機(jī)制幾乎一樣挣郭,但由于Hashtable是一個(gè)古老的迄埃、線程安全的集合,因此HashMap通常比Hashtable要快兑障。
TreeMap通常比HashMap侄非、Hashtable要慢,因?yàn)門reeMap底層采用紅黑樹來管理key-value對(duì)流译。但是逞怨,TreeMap的key-value總是處于有序狀態(tài)。
對(duì)于一般場(chǎng)景福澡,程序應(yīng)該多考慮使用HashMap叠赦,因?yàn)镠ashMap正是為快速查詢?cè)O(shè)計(jì)的。但是如果程序需要一個(gè)總是排好序的Map時(shí)革砸,則可以考慮使用TreeMap
LinkedHashMap比HashMap慢一點(diǎn)除秀,因?yàn)樗枰S護(hù)鏈表來保持Map中key-value的添加順序
IdentityHashMap性能沒有特別出色處,它采用與HashMap相似的實(shí)現(xiàn)算利,只是它使用==而不是equals()方法來判斷元素相等册踩。EnumMap性能最好,它只能使用一個(gè)枚舉類的枚舉值作為key效拭。
HashSet和HashMap暂吉、Hashtable的構(gòu)造器允許指定一個(gè)負(fù)載極限胖秒,HashSet和HashMap、Hashtable的默認(rèn)“負(fù)載極限”是0.75.