Java集合1-Map總結(jié)

聲明:原創(chuàng)文章,轉(zhuǎn)載請注明出處。http://m.itdecent.cn/u/e02df63eaa87

Java集合系列
Java集合1-Map總結(jié)
Java集合2-HashMap詳解(含源碼分析)

1、Map

Map主要用于存儲健值對,根據(jù)鍵得到值,因此不允許鍵重復(fù),但允許值重復(fù)。

2、HashMap

Hashmap 是一個(gè)最常用的Map,它根據(jù)鍵的HashCode值存儲數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度,遍歷時(shí),取得數(shù)據(jù)的順序是完全隨機(jī)的。

  • HashMap最多只允許一條記錄的鍵為Null;允許多條記錄的值為 Null;
  • HashMap不支持線程的同步,即任一時(shí)刻可以有多個(gè)線程同時(shí)寫HashMap;可能會導(dǎo)致數(shù)據(jù)的不一致。
  • HashMap在多線程情況下,rehash過程中有可能導(dǎo)致Entry產(chǎn)生環(huán)形鏈,導(dǎo)致程序出現(xiàn)死循環(huán)。

如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。

3、HashTable

Hashtable與 HashMap類似,它繼承自Dictionary類,不同的是:它不允許記錄的鍵或者值為空(空指針異常);它支持線程的同步,即任一時(shí)刻只有一個(gè)線程能寫Hashtable,因此也導(dǎo)致了 Hashtable在寫入時(shí)會比較慢。
HashTable容器使用synchronized來保證讀寫的線程安全,在競爭激烈的情況下效率非常低下。因?yàn)楫?dāng)一個(gè)線程訪問HashTable的同步方法時(shí),訪問其他同步方法的線程可能會進(jìn)入阻塞或者輪詢狀態(tài)。如線程1使用put添加元素,線程2不但不能使用put添加元素,也不能使用get獲取元素,因此競爭越激烈效率越低。

4、LinkedHashMap

LinkedHashMap 是HashMap的一個(gè)子類,保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時(shí),先得到的記錄肯定是先插入的。也可以在構(gòu)造時(shí)用帶參數(shù),按照訪問順序排序。
在遍歷的時(shí)候會比HashMap慢,不過有種情況例外,當(dāng)HashMap容量很大,實(shí)際數(shù)據(jù)較少時(shí),遍歷起來可能會比 LinkedHashMap慢,因?yàn)長inkedHashMap的遍歷速度只和實(shí)際數(shù)據(jù)有關(guān),和容量無關(guān),而HashMap的遍歷速度和他的容量有關(guān)。
根據(jù)鏈表中元素的順序可以分為:按插入順序的鏈表(默認(rèn),false),和按訪問順序的鏈表(調(diào)用get方法)。默認(rèn)是按插入順序排序,如果指定按訪問順序排序,那么調(diào)用get方法后,會將這次訪問的元素移至鏈表尾部,不斷訪問可以形成按訪問順序排序的鏈表。 可以重寫removeEldestEntry方法返回true值指定插入元素時(shí)移除最老的元素。

5、TreeMap

TreeMap實(shí)現(xiàn)SortMap接口,能夠把它保存的記錄根據(jù)鍵排序,默認(rèn)是按鍵值的升序排序,也可以指定排序的比較器,當(dāng)用Iterator 遍歷TreeMap時(shí),得到的記錄是排過序的。

6、ConcurrentHashMap

使用背景:

  • HashMap線程不安全。多線程進(jìn)行put()操作可能會引起死循環(huán)。這是因?yàn)?,多線程會導(dǎo)致HashMap的Entry鏈表形成環(huán)形結(jié)構(gòu),一旦形成環(huán)形結(jié)構(gòu),Entry的next節(jié)點(diǎn)永遠(yuǎn)不為空,就會產(chǎn)生死循環(huán)。
  • HashTable效率低下。HashTable使用Synchronized來保證線程安全,在線程競爭激烈的情況下,效率低下。因?yàn)楫?dāng)一個(gè)線程訪問HashTable的同步方法(put),其他線程也訪問HashTable的同步方法(put/get)時(shí),會進(jìn)入阻塞或輪詢狀態(tài)。

ConcurrentHashMap在JDK1.7版本使用分段鎖技術(shù),將數(shù)據(jù)分成一段一段的存儲,然后給每一段數(shù)據(jù)配一把鎖,當(dāng)一個(gè)線程占用鎖訪問一個(gè)段數(shù)據(jù)時(shí),其他段的數(shù)據(jù)也能被其他線程訪問,能實(shí)現(xiàn)并發(fā)訪問。而在JDK1.8版本上,則采用CAS+Synchronized的方式實(shí)現(xiàn)并發(fā)訪問。

7、總結(jié)

一般情況下,我們用的最多的是HashMap,在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。
但如果您要按自然順序或自定義順序遍歷鍵,那么TreeMap會更好。
如果需要輸出的順序和輸入的相同,那么用LinkedHashMap 可以實(shí)現(xiàn),它還可以按讀取順序來排列。

HashMap是一個(gè)最常用的Map,它根據(jù)鍵的hashCode值存儲數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度。HashMap最多只允許一條記錄的鍵為NULL,允許多條記錄的值為NULL。

HashMap不支持線程同步,即任一時(shí)刻可以有多個(gè)線程同時(shí)寫HashMap,可能會導(dǎo)致數(shù)據(jù)的不一致性。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力。

Hashtable與HashMap類似,不同的是:它不允許記錄的鍵或者值為空;它支持線程的同步,即任一時(shí)刻只有一個(gè)線程能寫Hashtable,因此也導(dǎo)致了Hashtable在寫入時(shí)會比較慢。
LinkedHashMap保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時(shí),先得到的記錄肯定是先插入的。

在遍歷的時(shí)候會比HashMap慢TreeMap能夠把它保存的記錄根據(jù)鍵排序,默認(rèn)是按升序排序,也可以指定排序的比較器。當(dāng)用Iterator遍歷TreeMap時(shí),得到的記錄是排過序的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前面已經(jīng)介紹完了Collection接口下的集合實(shí)現(xiàn)類,今天我們來介紹Map接口下的兩個(gè)重要的集合實(shí)現(xiàn)類HashM...
    Ruheng閱讀 10,545評論 2 38
  • Java SE 基礎(chǔ): 封裝、繼承、多態(tài) 封裝: 概念:就是把對象的屬性和操作(或服務(wù))結(jié)合為一個(gè)獨(dú)立的整體,并盡...
    Jayden_Cao閱讀 2,259評論 0 8
  • 集合類簡介 為什么出現(xiàn)集合類?面向?qū)ο笳Z言對事物的體現(xiàn)都是以對象的形式,所以為了方便對多個(gè)對象的操作,就要對對象進(jìn)...
    阿敏其人閱讀 1,566評論 0 7
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,891評論 11 349
  • 冬日里寒風(fēng)刺骨 汽車?yán)镂因榭s著身體 顫抖著在漆黑的路上 淚水緩緩順著眼角流下 卻不是因?yàn)楹L(fēng)迷了雙眼 只有在夜里 ...
    藍(lán)色風(fēng)鈴草閱讀 207評論 2 4

友情鏈接更多精彩內(nèi)容