Java中Map, List, Set和Queue的区别和使用场景
轉(zhuǎn):https://blog.csdn.net/kingcat666/article/details/75579632
1. Java集合類基本概念
在編程中,常常需要集中存放多個(gè)數(shù)據(jù)。從傳統(tǒng)意義上講,數(shù)組是我們的一個(gè)很好的選擇,前提是我們事先已經(jīng)明確知道我們將要保存的對(duì)象的數(shù)量。一旦在數(shù)組初始化時(shí)指定了這個(gè)數(shù)組長(zhǎng)度,這個(gè)數(shù)組長(zhǎng)度就是不可變的,如果我們需要保存一個(gè)可以動(dòng)態(tài)增長(zhǎng)的數(shù)據(jù)(在編譯時(shí)無(wú)法確定具體的數(shù)量),java的集合類就是一個(gè)很好的設(shè)計(jì)方案了。
集合類主要負(fù)責(zé)保存、盛裝其他數(shù)據(jù),因此集合類也被稱為容器類。所以的集合類都位于java.util包下,后來(lái)為了處理多線程環(huán)境下的并發(fā)安全問(wèn)題,java5還在java.util.concurrent包下提供了一些多線程支持的集合類。
Java容器類類庫(kù)的用途是"保存對(duì)象",并將其劃分為兩個(gè)不同的概念:
1) Collection
一組"對(duì)立"的元素,通常這些元素都服從某種規(guī)則
? 1.1) List必須保持元素特定的順序
? 1.2) Set不能有重復(fù)元素
? 1.3) Queue保持一個(gè)隊(duì)列(先進(jìn)先出)的順序
2) Map
一組成對(duì)的"鍵值對(duì)"對(duì)象
Collection和Map的區(qū)別在于容器中每個(gè)位置保存的元素個(gè)數(shù):
1) Collection 每個(gè)位置只能保存一個(gè)元素(對(duì)象)
?
2) Map保存的是"鍵值對(duì)",就像一個(gè)小型數(shù)據(jù)庫(kù)。我們可以通過(guò)"鍵"找到該鍵對(duì)應(yīng)的"值"
2. Java集合類架構(gòu)層次關(guān)系
1. Interface Iterable
迭代器接口,這是Collection類的父接口。實(shí)現(xiàn)這個(gè)Iterable接口的對(duì)象允許使用foreach進(jìn)行遍歷,也就是說(shuō),所有的Collection集合對(duì)象都具有"foreach可遍歷性"。這個(gè)Iterable接口只
有一個(gè)方法:?iterator()。它返回一個(gè)代表當(dāng)前集合對(duì)象的泛型<T>迭代器,用于之后的遍歷操作
1.1 Collection
Collection是最基本的集合接口,一個(gè)Collection代表一組Object的集合,這些Object被稱作Collection的元素。Collection是一個(gè)接口,用以提供規(guī)范定義,不能被實(shí)例化使用
? ? 1) Set
? ? Set集合類似于一個(gè)罐子,"丟進(jìn)"Set集合里的多個(gè)對(duì)象之間沒(méi)有明顯的順序。Set繼承自Collection接口,不能包含有重復(fù)元素(記住,這是整個(gè)Set類層次的共有屬性)。
? ? Set判斷兩個(gè)對(duì)象相同不是使用"=="運(yùn)算符,而是根據(jù)equals方法。也就是說(shuō),我們?cè)诩尤胍粋€(gè)新元素的時(shí)候,如果這個(gè)新元素對(duì)象和Set中已有對(duì)象進(jìn)行注意equals比較都返回false,則Set就會(huì)接受這個(gè)新元素對(duì)象,否則拒絕。
? ? 因?yàn)镾et的這個(gè)制約,在使用Set集合的時(shí)候,應(yīng)該注意兩點(diǎn):
1) 為Set集合里的元素的實(shí)現(xiàn)類實(shí)現(xiàn)一個(gè)有效的equals(Object)方法、
2) 對(duì)Set的構(gòu)造函數(shù),傳入的Collection參數(shù)不能包含重復(fù)的元素
? ? ? ? 1.1) HashSet
? ? ? ? HashSet是Set接口的典型實(shí)現(xiàn),HashSet使用HASH算法來(lái)存儲(chǔ)集合中的元素,因此具有良好的存取和查找性能。當(dāng)向HashSet集合中存入一個(gè)元素時(shí),HashSet會(huì)調(diào)用該對(duì)象的hashCode()方法來(lái)得到該對(duì)象的hashCode值,然后根據(jù)該HashCode值決定該對(duì)象在HashSet中的存儲(chǔ)位置。
? ? ? ? 值得注意的是,HashSet集合判斷兩個(gè)元素相等的標(biāo)準(zhǔn)是兩個(gè)對(duì)象通過(guò)equals()方法比較相等,并且兩個(gè)對(duì)象的hashCode()方法的返回值相等
? ? ? ? ? ? 1.1.1) LinkedHashSet
? ? ? ? ? ? LinkedHashSet集合也是根據(jù)元素的hashCode值來(lái)決定元素的存儲(chǔ)位置,但和HashSet不同的是,它同時(shí)使用鏈表維護(hù)元素的次序,這樣使得元素看起來(lái)是以插入的順序保存的。
當(dāng)遍歷LinkedHashSet集合里的元素時(shí),LinkedHashSet將會(huì)按元素的添加順序來(lái)訪問(wèn)集合里的元素。LinkedHashSet需要維護(hù)元素的插入順序,因此性能略低于HashSet的性能,但在迭代訪問(wèn)Set里的全部元素時(shí)(遍歷)將有很好的性能(鏈表很適合進(jìn)行遍歷)
? ? ? ? 1.2) SortedSet ? ?
? ? ? ? 此接口主要用于排序操作,即實(shí)現(xiàn)此接口的子類都屬于排序的子類
? ? ? ? ? ? 1.2.1) TreeSet
? ? ? ? ? ? TreeSet是SortedSet接口的實(shí)現(xiàn)類,TreeSet可以確保集合元素處于排序狀態(tài)
? ? ? ? 1.3) EnumSet
? ? ? ? EnumSet是一個(gè)專門為枚舉類設(shè)計(jì)的集合類,EnumSet中所有元素都必須是指定枚舉類型的枚舉值,該枚舉類型在創(chuàng)建EnumSet時(shí)顯式、或隱式地指定。EnumSet的集合元素也是有序的,
它們以枚舉值在Enum類內(nèi)的定義順序來(lái)決定集合元素的順序
? ??2) List
? ? List集合代表一個(gè)元素有序、可重復(fù)的集合,集合中每個(gè)元素都有其對(duì)應(yīng)的順序索引。List集合允許加入重復(fù)元素,因?yàn)樗梢酝ㄟ^(guò)索引來(lái)訪問(wèn)指定位置的集合元素。List集合默認(rèn)按元素的添加順序設(shè)置元素的索引
? ? ? ? 2.1) ArrayList
? ? ? ? ArrayList是基于數(shù)組實(shí)現(xiàn)的List類,它封裝了一個(gè)動(dòng)態(tài)的增長(zhǎng)的、允許再分配的Object[]數(shù)組。
? ? ? ? 2.2) Vector
? ? ? ? Vector和ArrayList在用法上幾乎完全相同,但由于Vector是一個(gè)古老的集合,所以Vector提供了一些方法名很長(zhǎng)的方法,但隨著JDK1.2以后,java提供了系統(tǒng)的集合框架,就將Vector改為實(shí)現(xiàn)List接口,統(tǒng)一歸入集合框架體系中
? ? ? ? ? ? 2.2.1) Stack
? ? ? ? ? ? Stack是Vector提供的一個(gè)子類,用于模擬"棧"這種數(shù)據(jù)結(jié)構(gòu)(LIFO后進(jìn)先出)
? ? ? ? 2.3) LinkedList
? ? ? ? implements List<E>, Deque<E>。實(shí)現(xiàn)List接口,能對(duì)它進(jìn)行隊(duì)列操作,即可以根據(jù)索引來(lái)隨機(jī)訪問(wèn)集合中的元素。同時(shí)它還實(shí)現(xiàn)Deque接口,即能將LinkedList當(dāng)作雙端隊(duì)列使用。自然也可以被當(dāng)作"棧來(lái)使用"
? ??3) Queue
? ? Queue用于模擬"隊(duì)列"這種數(shù)據(jù)結(jié)構(gòu)(先進(jìn)先出 FIFO)。隊(duì)列的頭部保存著隊(duì)列中存放時(shí)間最長(zhǎng)的元素,隊(duì)列的尾部保存著隊(duì)列中存放時(shí)間最短的元素。新元素插入(offer)到隊(duì)列的尾部,訪問(wèn)元素(poll)操作會(huì)返回隊(duì)列頭部的元素,隊(duì)列不允許隨機(jī)訪問(wèn)隊(duì)列中的元素。結(jié)合生活中常見的排隊(duì)就會(huì)很好理解這個(gè)概念
? ? ? ? 3.1) PriorityQueue
? ? ? ? PriorityQueue并不是一個(gè)比較標(biāo)準(zhǔn)的隊(duì)列實(shí)現(xiàn),PriorityQueue保存隊(duì)列元素的順序并不是按照加入隊(duì)列的順序,而是按照隊(duì)列元素的大小進(jìn)行重新排序,這點(diǎn)從它的類名也可以看出來(lái)
? ? ? ? 3.2) Deque
? ? ? ? Deque接口代表一個(gè)"雙端隊(duì)列",雙端隊(duì)列可以同時(shí)從兩端來(lái)添加、刪除元素,因此Deque的實(shí)現(xiàn)類既可以當(dāng)成隊(duì)列使用、也可以當(dāng)成棧使用
? ? ? ? ? ? 3.2.1) ArrayDeque
? ? ? ? ? ? 是一個(gè)基于數(shù)組的雙端隊(duì)列,和ArrayList類似,它們的底層都采用一個(gè)動(dòng)態(tài)的、可重分配的Object[]數(shù)組來(lái)存儲(chǔ)集合元素,當(dāng)集合元素超出該數(shù)組的容量時(shí),系統(tǒng)會(huì)在底層重新分配一個(gè)Object[]數(shù)組來(lái)存儲(chǔ)集合元素
? ? ? ? ? ? 3.2.2) LinkedList
1.2 Map
? ? Map用于保存具有"映射關(guān)系"的數(shù)據(jù),因此Map集合里保存著兩組值,一組值用于保存Map里的key,另外一組值用于保存Map里的value。key和value都可以是任何引用類型的數(shù)據(jù)。Map的key不允許重復(fù),即同一個(gè)Map對(duì)象的任何兩個(gè)key通過(guò)equals方法比較結(jié)果總是返回false。
? ? 關(guān)于Map,我們要從代碼復(fù)用的角度去理解,java是先實(shí)現(xiàn)了Map,然后通過(guò)包裝了一個(gè)所有value都為null的Map就實(shí)現(xiàn)了Set集合。Map的這些實(shí)現(xiàn)類和子接口中key集的存儲(chǔ)形式和Set集合完全相同(即key不能重復(fù))
? ? Map的這些實(shí)現(xiàn)類和子接口中value集的存儲(chǔ)形式和List非常類似(即value可以重復(fù)、根據(jù)索引來(lái)查找)
? ??1) HashMap
? ? 和HashSet集合不能保證元素的順序一樣,HashMap也不能保證key-value對(duì)的順序。并且類似于HashSet判斷兩個(gè)key是否相等的標(biāo)準(zhǔn)也是: 兩個(gè)key通過(guò)equals()方法比較返回true、同時(shí)兩個(gè)key的hashCode值也必須相等
? ? ? ? 1.1) LinkedHashMap
? ? ? ? LinkedHashMap也使用雙向鏈表來(lái)維護(hù)key-value對(duì)的次序,該鏈表負(fù)責(zé)維護(hù)Map的迭代順序,與key-value對(duì)的插入順序一致(注意和TreeMap對(duì)所有的key-value進(jìn)行排序進(jìn)行區(qū)分)
? ??2) Hashtable
? ? 是一個(gè)古老的Map實(shí)現(xiàn)類
? ? ? ? 2.1) Properties?
? ? ? ? Properties對(duì)象在處理屬性文件時(shí)特別方便(windows平臺(tái)上的.ini文件),Properties類可以把Map對(duì)象和屬性文件關(guān)聯(lián)起來(lái),從而可以把Map對(duì)象中的key-value對(duì)寫入到屬性文件中,也可以把屬性文件中的"屬性名-屬性值"加載到Map對(duì)象中
? ??3) SortedMap
? ? 正如Set接口派生出SortedSet子接口,SortedSet接口有一個(gè)TreeSet實(shí)現(xiàn)類一樣,Map接口也派生出一個(gè)SortedMap子接口,SortedMap接口也有一個(gè)TreeMap實(shí)現(xiàn)類
? ? ? ? 3.1) TreeMap
? ? ? ? TreeMap就是一個(gè)紅黑樹數(shù)據(jù)結(jié)構(gòu),每個(gè)key-value對(duì)即作為紅黑樹的一個(gè)節(jié)點(diǎn)。TreeMap存儲(chǔ)key-value對(duì)(節(jié)點(diǎn))時(shí),需要根據(jù)key對(duì)節(jié)點(diǎn)進(jìn)行排序。TreeMap可以保證所有的key-value對(duì)處于有序狀態(tài)。同樣,TreeMap也有兩種排序方式: 自然排序、定制排序
? ??4) WeakHashMap
? ? WeakHashMap與HashMap的用法基本相似。區(qū)別在于,HashMap的key保留了對(duì)實(shí)際對(duì)象的"強(qiáng)引用",這意味著只要該HashMap對(duì)象不被銷毀,該HashMap所引用的對(duì)象就不會(huì)被垃圾回收。
但WeakHashMap的key只保留了對(duì)實(shí)際對(duì)象的弱引用,這意味著如果WeakHashMap對(duì)象的key所引用的對(duì)象沒(méi)有被其他強(qiáng)引用變量所引用,則這些key所引用的對(duì)象可能被垃圾回收,當(dāng)垃圾回收了該key所對(duì)應(yīng)的實(shí)際對(duì)象之后,WeakHashMap也可能自動(dòng)刪除這些key所對(duì)應(yīng)的key-value對(duì)
? ??5) IdentityHashMap
? ? IdentityHashMap的實(shí)現(xiàn)機(jī)制與HashMap基本相似,在IdentityHashMap中,當(dāng)且僅當(dāng)兩個(gè)key嚴(yán)格相等(key1 == key2)時(shí),IdentityHashMap才認(rèn)為兩個(gè)key相等
? ??6) EnumMap
? ? EnumMap是一個(gè)與枚舉類一起使用的Map實(shí)現(xiàn),EnumMap中的所有key都必須是單個(gè)枚舉類的枚舉值。創(chuàng)建EnumMap時(shí)必須顯式或隱式指定它對(duì)應(yīng)的枚舉類。EnumMap根據(jù)key的自然順序
3. Java集合類使用場(chǎng)景規(guī)則
Set集合:
1) HashSet的性能總是比TreeSet好(特別是最常用的添加、查詢?cè)氐炔僮?,因?yàn)門reeSet需要額外的紅黑樹算法來(lái)維護(hù)集合元素的次序。只有當(dāng)需要一個(gè)保持排序的Set時(shí),才應(yīng)該使用TreeSet,否則都應(yīng)該使用HashSet 2) 對(duì)于普通的插入、刪除操作,LinkedHashSet比HashSet要略慢一點(diǎn),這是由維護(hù)鏈表所帶來(lái)的開銷造成的。不過(guò),因?yàn)橛辛随湵淼拇嬖?#xff0c;遍歷LinkedHashSet會(huì)更快 3) EnumSet是所有Set實(shí)現(xiàn)類中性能最好的,但它只能保存同一個(gè)枚舉類的枚舉值作為集合元素 4) HashSet、TreeSet、EnumSet都是"線程不安全"的,通常可以通過(guò)Collections工具類的synchronizedSortedSet方法來(lái)"包裝"該Set集合。 SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));?
List集合:
1. java提供的List就是一個(gè)"線性表接口",ArrayList(基于數(shù)組的線性表)、LinkedList(基于鏈的線性表)是線性表的兩種典型實(shí)現(xiàn) 2. Queue代表了隊(duì)列,Deque代表了雙端隊(duì)列(既可以作為隊(duì)列使用、也可以作為棧使用) 3. 因?yàn)閿?shù)組以一塊連續(xù)內(nèi)存來(lái)保存所有的數(shù)組元素,所以數(shù)組在隨機(jī)訪問(wèn)時(shí)性能最好。所以的內(nèi)部以數(shù)組作為底層實(shí)現(xiàn)的集合在隨機(jī)訪問(wèn)時(shí)性能最好。 4. 內(nèi)部以鏈表作為底層實(shí)現(xiàn)的集合在執(zhí)行插入、刪除操作時(shí)有很好的性能 5. 進(jìn)行迭代操作時(shí),以鏈表作為底層實(shí)現(xiàn)的集合比以數(shù)組作為底層實(shí)現(xiàn)的集合性能好
Map集合:
總結(jié)
以上是生活随笔為你收集整理的Java中Map, List, Set和Queue的区别和使用场景的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java JDK中文帮助文档免费下载,百
- 下一篇: 变换上三角矩阵_关于马尔可夫矩阵的一些个