Java集合List、Set、Map
集合是 java 基礎(chǔ)中非常重要的一部分,同樣也是 Java 面試中很重要的一個(gè)知識(shí)點(diǎn)。所以,給王小整理了這篇關(guān)于集合的文章。
1、接口繼承關(guān)系以及實(shí)現(xiàn)
集合類存放于 Java.util 包中,主要有 3 種:set、list 和 map。
- Collection:Collection 是集合 List、Set、Queue 的最基本的接口
- Iterator:迭代器,可以通過迭代器遍歷集合中的數(shù)據(jù)
- Map:是映射表的基礎(chǔ)接口
層次關(guān)系圖:
2、List
Java 的 List 是非常常用的數(shù)據(jù)類型。List 是有序的 Collection。Java List 一共三個(gè)實(shí)現(xiàn)類:分別是 ArrayList、Vector 和 LinkedList。
2.1、ArrayList
ArrayList 是最常用的 List 實(shí)現(xiàn)類,內(nèi)部是通過數(shù)組實(shí)現(xiàn)的,它允許對(duì)元素進(jìn)行快速隨機(jī)訪問。數(shù)組的缺點(diǎn)是每個(gè)元素之間不能有間隔,當(dāng)數(shù)組大小不滿足時(shí)需要增加存儲(chǔ)能力,就要將已經(jīng)有數(shù)組的數(shù)據(jù)復(fù)制到新的存儲(chǔ)空間中。當(dāng)從 ArrayList 的中間位置插入或者刪除元素時(shí),需要對(duì)數(shù)組進(jìn)行復(fù)制、移動(dòng)、代價(jià)比較高。因此,它適合隨機(jī)查找和遍歷,不適合插入和刪除。
2.2、Vector
Vector 與 ArrayList 一樣,也是通過數(shù)組實(shí)現(xiàn)的,不同的是它支持線程的同步,即某一時(shí)刻只有一個(gè)線程能夠?qū)?Vector,避免多線程同時(shí)寫而引起的不一致性,但實(shí)現(xiàn)同步需要很高的花費(fèi),因此,訪問它比訪問 ArrayList 慢。
2.3、LinkList
LinkedList 是用鏈表結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)的,很適合數(shù)據(jù)的動(dòng)態(tài)插入和刪除,隨機(jī)訪問和遍歷速度比較慢。另外,他還提供了 List 接口中沒有定義的方法,專門用于操作表頭和表尾元素,可以當(dāng)作堆棧、隊(duì)列和雙向隊(duì)列使用。
3、Set
Set 注重獨(dú)一無二的性質(zhì),該體系集合用于存儲(chǔ)無序(存入和取出的順序不一定相同)元素,值不能重復(fù)。對(duì)象的相等性本質(zhì)是對(duì)象 hashCode 值(java 是依據(jù)對(duì)象的內(nèi)存地址計(jì)算出的此序號(hào))判斷的,如果想要讓兩個(gè)不同的對(duì)象視為相等的,就必須覆蓋 Object 的 hashCode 方法和 equals 方法。java Set 一共三個(gè)實(shí)現(xiàn)類:分別是 HashSet、TreeSet 和 LinkHashSet。
3.1、HashSet
哈希表邊存放的是哈希值。HashSet 存儲(chǔ)元素的順序并不是按照存入時(shí)的順序(和 List 顯然不同) 而是按照哈希值來存的所以取數(shù)據(jù)也是按照哈希值取得。元素的哈希值是通過元素的hashcode 方法來獲取的, HashSet 首先判斷兩個(gè)元素的哈希值,如果哈希值一樣,接著會(huì)比較equals 方法 如果 equls 結(jié)果為 true ,HashSet 就視為同一個(gè)元素。如果 equals 為 false 就不是同一個(gè)元素。
哈希值相同 equals 為 false 的元素是怎么存儲(chǔ)呢,就是在同樣的哈希值下順延(可以認(rèn)為哈希值相同的元素放在一個(gè)哈希桶中)。也就是哈希一樣的存一列。如圖 1 表示 hashCode 值不相同的情況;圖 2 表示 hashCode 值相同,但 equals 不相同的情況。
HashSet 通過 hashCode 值來確定元素在內(nèi)存中的位置。一個(gè) hashCode 位置上可以存放多個(gè)元素。
3.2、TreeSet
3.3、LinkHashSet
對(duì)于 LinkedHashSet 而言,它繼承與 HashSet、又基于 LinkedHashMap 來實(shí)現(xiàn)的。
LinkedHashSet 底層使用 LinkedHashMap 來保存所有元素,它繼承與 HashSet,其所有的方法操作上又與 HashSet 相同,因此 LinkedHashSet 的實(shí)現(xiàn)上非常簡單,只提供了四個(gè)構(gòu)造方法,并通過傳遞一個(gè)標(biāo)識(shí)參數(shù),調(diào)用父類的構(gòu)造器,底層構(gòu)造一個(gè) LinkedHashMap 來實(shí)現(xiàn),在相關(guān)操作上與父類 HashSet 的操作相同,直接調(diào)用父類 HashSet 的方法即可。
4、Map
4.1、HashMap
HashMap 根據(jù)鍵的 hashCode 值存儲(chǔ)數(shù)據(jù),大多數(shù)情況下可以直接定位到它的值,因而具有很快的訪問速度,但遍歷順序卻是不確定的。 HashMap 最多只允許一條記錄的鍵為 null,允許多條記錄的值為 null。HashMap 非線程安全,即任一時(shí)刻可以有多個(gè)線程同時(shí)寫 HashMap,可能會(huì)導(dǎo)致數(shù)據(jù)的不一致。如果需要滿足線程安全,可以用 Collections 的 synchronizedMap 方法使HashMap 具有線程安全的能力,或者使用 ConcurrentHashMap。
4.2、HashTable
Hashtable 是遺留類,很多映射的常用功能與 HashMap 類似,不同的是它承自 Dictionary 類,
并且是線程安全的,任一時(shí)間只有一個(gè)線程能寫 Hashtable,并發(fā)性不如 ConcurrentHashMap,
因?yàn)?ConcurrentHashMap 引入了分段鎖。Hashtable 不建議在新代碼中使用,不需要線程安全
的場合可以用 HashMap 替換,需要線程安全的場合可以用 ConcurrentHashMap 替換。
#####4.3、TreeMap
TreeMap 實(shí)現(xiàn) SortedMap 接口,能夠把它保存的記錄根據(jù)鍵排序,默認(rèn)是按鍵值的升序排序,
也可以指定排序的比較器,當(dāng)用 Iterator 遍歷 TreeMap 時(shí),得到的記錄是排過序的。
如果使用排序的映射,建議使用 TreeMap。
4.4、LinkHashMap
LinkedHashMap 是 HashMap 的一個(gè)子類,保存了記錄的插入順序,在用 Iterator 遍歷LinkedHashMap 時(shí),先得到的記錄肯定是先插入的,也可以在構(gòu)造時(shí)帶參數(shù),按照訪問次序
5、總結(jié)
1、三者之間的區(qū)別
- list 有序、可以重復(fù),有三個(gè)實(shí)現(xiàn)類,ArrayList、linkedList、Vector
- set 無序、不可重復(fù),有兩個(gè)實(shí)現(xiàn)類,HashSet、LinkedhashSet
- map 鍵不可以重復(fù)、值可以重復(fù),有三個(gè)實(shí)現(xiàn)類,HashMap、HashTable、LinkedHashMap
2、List 三個(gè)子類的區(qū)別
- ArrayList:底層使用object[]數(shù)組實(shí)現(xiàn),內(nèi)存地址都是連續(xù)的便于索引,查詢快;在新增的時(shí)候需要申請(qǐng)一塊連續(xù)的內(nèi)存空間,所以增刪比較慢。
- LinkedList: 底層是基于鏈表實(shí)現(xiàn),鏈表內(nèi)存是散亂的,在儲(chǔ)存自身內(nèi)存地址的
同時(shí),還儲(chǔ)存著下一個(gè)元素的內(nèi)存地址,所以查詢慢,增刪快。 - Vector:底層數(shù)組實(shí)現(xiàn),由于所有的方法都是采用synchronize,線程安全,效率慢。
3、map 三個(gè)子類的區(qū)別
- HashMap:基于hash表的Map接口實(shí)現(xiàn),非線程安全,支持鍵null、值null
- HashTab:線程安全,不支持鍵null,值null
- LinkedHashMap:持兩種排序:插入順序、訪問順序。前者是指按照插入時(shí)的順序排序,后者是指按照最舊使用到最近使用的順序
4、set 兩個(gè)子類的區(qū)別
- HashSet:底層由HashMap實(shí)現(xiàn)
- LinkedHashSet:LinkedHashSet 繼承自 HashSet,源碼更少、更簡單,唯一的區(qū)別是 LinkedHashSet 內(nèi)部使用的是 LinkHashMap。這樣做的意義或者好處就是 LinkedHashSet 中的元素順序是可以保證的,也就是說遍歷序和插入序是一致的
如果文章有錯(cuò)的地方歡迎指正,大家互相留言交流。習(xí)慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號(hào):niceyoo
總結(jié)
以上是生活随笔為你收集整理的Java集合List、Set、Map的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java笔试题算法题,吐血整理
- 下一篇: Java异常分类及处理