Java集合中的WeakHashMap、IdentityHashMap、EnumMap詳解
WeakHashMap
WeakHashMap與HashMap的用法基本類似。
區(qū)別:
- HashMap的key保留了對實(shí)際對象的強(qiáng)引用,這意味著只要HashMap對象不被銷毀,還HashMap的所有key所引用的對象就不會(huì)被垃圾回收,HashMap也不會(huì)自動(dòng)刪除這些key所對應(yīng)的key-value對;
- WeakHashMap的key只保留對實(shí)際對象的弱引用,這意味著如果WeakHashMap對象的key所引用的對象沒有被其他強(qiáng)引用變量所引用,則這些key所引用的對象可能被垃圾回收,WeakHashMap也可能自動(dòng)刪除這些key所對應(yīng)的key-value對。
- WeakHashMap中的每個(gè)key對象只持有對實(shí)際對象的弱引用,因此,當(dāng)垃圾回收了該key所對應(yīng)的實(shí)際對象之后,WeakHashMap會(huì)自動(dòng)刪除該key對應(yīng)的key-value對。
注意:
如果需要使用WeakHashMap的key來保留對象的弱引用,則不要讓該key所引用的對象具有任何強(qiáng)引用,否則將失去WeakHashMap的意義。
示例:
package com.map; import java.util.WeakHashMap; public class WeakHashMapTest { public static void main(String[] args) { WeakHashMap wak = new WeakHashMap(); //兩個(gè)key都是匿名字符串對象(沒有其他引用) wak.put(new String("數(shù)學(xué)"), new String("優(yōu)良")); wak.put(new String("語文"), new String("良好")); //該key是一個(gè)系統(tǒng)緩存的字符串對象 wak.put("java", new String("好"));① System.out.println(wak); //{java=良好, 數(shù)學(xué)=優(yōu)良, 語文=良好} //通知系統(tǒng)進(jìn)行垃圾回收 System.gc(); System.runFinalization(); System.out.println(wak);//{java=好} } }
結(jié)果上來看:當(dāng)系統(tǒng)進(jìn)行垃圾時(shí),刪除了WeakHashMap 對象的前兩個(gè)key-value對,因?yàn)樘砑忧皟蓚€(gè)key-value對時(shí),這兩個(gè)key都是匿名的字符串對象,WeakHashMap 只保留了對它們的弱引用,這樣垃圾回收時(shí)會(huì)自動(dòng)刪除這兩個(gè)key-value對。
WeakHashMap對象中①標(biāo)示處的key是一個(gè)字符串直接量(系統(tǒng)會(huì)自動(dòng)保留對該字符串對象的強(qiáng)引用),所以垃圾回收時(shí)不會(huì)回收它。
IdentityHashMap
在IdentityHashMap中,當(dāng)且僅當(dāng)兩個(gè)key嚴(yán)格相等(key1==key2)時(shí),IdentityHashMap才認(rèn)為兩個(gè)key相等;相對于普通HashMap而言,只要key1和key2通過equals()方法返回true,且它們的hashCode值相等即可。
注意:
IdentityHashMap是一個(gè)特殊的Map實(shí)現(xiàn)!此類實(shí)現(xiàn)Map接口時(shí),它有意違反Map的通常規(guī)范:IdentityHashMap要求兩個(gè)key嚴(yán)格相等才認(rèn)為兩個(gè)key相等。IdentityHashMap不保證key-value對之間的順序,更不能保證它們的順序隨時(shí)間的推移保持不變。
示例:
package com.map; import java.util.IdentityHashMap; public class IdentityHashMapTest { public static void main(String[] args) { IdentityHashMap idenmap = new IdentityHashMap(); idenmap.put(new String("語文"), 80); idenmap.put(new String("語文"), 89); idenmap.put("java", 80); idenmap.put("java", 80); System.out.println(idenmap); //{語文=80, java=80, 語文=89} } }
IdentityHashMap對象中添加了4個(gè)key-value對,前2個(gè)key-value對中的key是最新創(chuàng)建的字符串對象,它們通過==比較不相等,所以IdentityHashMap 會(huì)把他們當(dāng)成2個(gè)key來處理;后2個(gè)key-value都是字符串直接量,而且它們的字符序列完全相同,Java使用常量池來管理字符串直接量,所以它們通過==比較返回true,IdentityHashMap 會(huì)認(rèn)為它們是同一個(gè)key,因此只有一次可以添加成功。
EnumMap
EnumMap是一個(gè)與枚舉類一起使用的Map實(shí)現(xiàn),EnumMap中的所有key都必須是單個(gè)枚舉類的枚舉值。創(chuàng)建EnumMap時(shí)必須顯示或隱式的指定它對應(yīng)的枚舉類。
EnumMap特征:
- EnumMap在內(nèi)部以數(shù)組形式保存,所以這種實(shí)現(xiàn)形式非常緊湊、高效。
- EunmMap根據(jù)key的自然順序(即枚舉值在枚舉類中的定義順序)來維護(hù)key-value對的順序。
- EnumMap不允許使用null作為key,但允許使用null作為value。如果試圖使用null作為key時(shí)將拋出NullpointerException。
如果只是查詢是否包含值為null的key,或只是刪除值為null的key,都不會(huì)拋出異常。
與普通的Map有所區(qū)別的是,創(chuàng)建EnumMap是必須指定一個(gè)枚舉類,從而將該EnumMap和指定枚舉類關(guān)聯(lián)起來。
示例:
package com.map; import java.util.EnumMap; public class EnumMapTest { public static void main(String[] args) { EnumMap map = new EnumMap(Season.class); map.put(Season.SPRING, "春天"); map.put(Season.SUMMER, "夏天"); System.out.println(map); //{SPRING=春天, SUMMER=夏天} } } enum Season{ SPRING,SUMMER,FAIL,WINTER }
到此這篇關(guān)于Java集合中的WeakHashMap、IdentityHashMap、EnumMap詳解的文章就介紹到這了,更多相關(guān)Java的WeakHashMap和EnumMap、IdentityHashMap內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JetBrains?產(chǎn)品輸入激活碼?Key?is?invalid?完美解決方案
JetBrains?系列產(chǎn)品(IDEA、Pycharm?等)使用本站破解教程?(opens?new?window),在輸入激活碼時(shí),部分小伙伴反應(yīng)說提示?Key?is?invalid?無法激活,今天小編給大家分享完美解決方案,感興趣的朋友跟隨小編一起看看吧2022-11-11java實(shí)現(xiàn)代碼統(tǒng)計(jì)小程序
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)代碼統(tǒng)計(jì)小程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09SpringBoot+Mybatis實(shí)現(xiàn)登錄注冊的示例代碼
這篇文章主要介紹了SpringBoot+Mybatis實(shí)現(xiàn)登錄注冊的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Spring Boot下如何自定義Repository中的DAO方法
這篇文章主要介紹了Spring Boot下如何自定義Repository中的DAO方法,需要的朋友可以參考下2017-06-06