面試時(shí)時(shí)被集合類(lèi)各種虐,現(xiàn)在就來(lái)總結(jié)一下Java的集合類(lèi)及其區(qū)別。
Java集合框架的基本接口、類(lèi)層級(jí)結(jié)果如下:
java.util.Collection[接口]
--java.util.List[接口]
--java.util.AarrayList
--java.util.LinkedList
--java.util.Vector
--java.util.Stack
--java.util.Set[接口]
--java.util.HashSet
--java.util.SortedSet[接口]
--java.util.TreeSet
--java.util.Queue
java.util.Map[接口]
--java.util.SortedMap[接口]
--java.util.TreeMap
--java.util.HashMap
--java.util.HashTable
--java.util.LinkedHashMap
--java.util.WeakHashMap
1.Collection
是最基本的集合類(lèi)型,所有實(shí)現(xiàn)Collection接口的類(lèi)都必須提供兩個(gè)標(biāo)準(zhǔn)的構(gòu)造函數(shù):無(wú)參數(shù)的構(gòu)造函數(shù)用于創(chuàng)建一個(gè)共的Collection,有一個(gè)Collection參數(shù)的構(gòu)造函數(shù)用于創(chuàng)建一個(gè)新的Collection,這個(gè)新的Collection與傳入的Collection有相同的元素。
若要檢查Collection中的元素,可以使用foreach進(jìn)行遍歷,也可以使用迭代器,Collection支持iterator()方法,通過(guò)該方法可以訪問(wèn)Collection中的每一個(gè)元素。用法如下:
Iterator it=collection.iterator();
while(it.hasNext()){
Object obj=it.next();
}
Set和List是由Collection派生的兩個(gè)接口
1.1 List接口
List是有序的Collection,使用此接口能夠精確的控制每個(gè)元素插入的位置。用戶(hù)能夠使用索引的位置來(lái)訪問(wèn)List中的元素,類(lèi)似于Java數(shù)組。
List允許有相同的元素存在。
除了具有Collection接口必備的的iterator()方法外,還提供了listIterator()方法,放回一個(gè) ListIterator接口。
實(shí)現(xiàn)List接口的常用類(lèi)有LinkedList、ArrayList、Vector和Stack
1.1.1 LinkedList類(lèi)
LinkedList實(shí)現(xiàn)了List類(lèi)接口,允許null元素。此外LinkedList提供額外的get、remove、insert方法在LinkedList的首部或尾部。這些操作使LinkedList可被用作堆棧(stack),隊(duì)列(queue)或雙向隊(duì)列(deque)
LinkedList沒(méi)有同步方法。如果多個(gè)線程想訪問(wèn)同一個(gè)List,則必須自己實(shí)現(xiàn)訪問(wèn)同步。一種解決辦法是在創(chuàng)建List時(shí)構(gòu)造一個(gè)同步的List:
List list=Collection。synchronizedList(new LinkedList(...))
1.1.2 ArrayList類(lèi)
ArrayList實(shí)現(xiàn)了可變大小的數(shù)組。它允許所有元素,包括null。ArrayList沒(méi)有同步。
size(),isEmpty(),get(),set()方法運(yùn)行時(shí)間為常數(shù)。但是add()方法開(kāi)銷(xiāo)為分?jǐn)偟某?shù),添加n個(gè)元素需要O(n)的時(shí)間。其他的方法運(yùn)行時(shí)間為線性。
每個(gè)ArrayList實(shí)例都有一個(gè)容量(Capactity),即用于存儲(chǔ)元素的數(shù)組的大小。這個(gè)容量可隨著不斷添加新元素而自動(dòng)增加,但是增長(zhǎng)算法并沒(méi)有定義。當(dāng)需要插入大量元素時(shí),在插入之前可以調(diào)用ensureCapacity()方法來(lái)增加ArrayList容量已提高插入效率
1.2Vector類(lèi)
Vector非常類(lèi)似ArrayList,當(dāng)時(shí)Vector是同步的。由Vector創(chuàng)建的iterator,雖然和ArrayLsit創(chuàng)建的iterator是同一接口,但是,因?yàn)閂ector是同步的,當(dāng)一個(gè)iterator被創(chuàng)建而且這在被使用,另一個(gè)線程改變了Vector狀態(tài),這時(shí)調(diào)用iterator的方法時(shí)將拋出ConcurrentModificationException,因此必須捕獲該異常。
1.3 Stack類(lèi)
Stack繼承自Vector,實(shí)現(xiàn)了一個(gè)后進(jìn)先出的堆棧。Stack提供了5個(gè)額外的方法使得Vector得以被當(dāng)做堆棧使用。基本的push和pop方法,還有peek方法得到棧頂?shù)脑?,empty方法測(cè)試堆棧是否為空,serach方法檢測(cè)一個(gè)元素在堆棧中的位置。Stack剛創(chuàng)建后是空棧。
1.4 Set接口
Set是一種不包含重復(fù)元素的Collection,即任意的兩個(gè)元素e1和e2都有e1.equals(e2)=false,Set最多有一個(gè)null元素。
很明顯,Set的構(gòu)造函數(shù)有一個(gè)約束條件,傳入的Collection參數(shù)不能包含重復(fù)的元素。
請(qǐng)注意:必須小心操作可變對(duì)象。如果一個(gè)Set中的可變?cè)馗淖兞俗陨淼臓顟B(tài)導(dǎo)致Object.equals(Object)=true將導(dǎo)致一些問(wèn)題
1.4.1 HashSet
HashSet調(diào)用對(duì)象的hashCode(),獲得哈希碼,然后在集合中計(jì)算存放對(duì)象的位置。通過(guò)比較哈希碼與equals()方法來(lái)判別是否重復(fù)。所以,重載了equals()方法同時(shí)也要重載hashCode();
1.4.2 TreeSet
TreeSet 繼承SortedSet接口,能夠?qū)现袑?duì)象排序。默認(rèn)排序方式是自然排序,但該方式只能對(duì)實(shí)現(xiàn)了Comparable接口的對(duì)象排序,java中對(duì)Integer、Byte、Double、Character、String等數(shù)值型和字符型對(duì)象都實(shí)現(xiàn)了該接口。
2 Map接口
Map沒(méi)有繼承Collection接口,Map提供key到value的映射。一個(gè)Map中不能包含相同的key,每個(gè)key只能映射一個(gè)value。Map接口提供了3中集合的視圖,Map的內(nèi)容可以被當(dāng)作一組key集合,一組value集合,或者一組key--value映射。
2.1 HashTable類(lèi)
HashTable繼承Map接口,實(shí)現(xiàn)了一個(gè)key--value映射的哈希表。任何非空的對(duì)象都可作為key或者value。
添加數(shù)據(jù)使用put(key,value),取出數(shù)據(jù)使用get(key),這兩個(gè)基本操作的時(shí)間開(kāi)銷(xiāo)為常數(shù)。
HashTable通過(guò)initial caoacity和load factor兩個(gè)參數(shù)調(diào)整性能。通常缺省的load factor 0.75較好地實(shí)現(xiàn)了時(shí)間和空間的均衡。增大了load factor可以節(jié)省空間但相應(yīng)的查找時(shí)間將增大,這回影響像get和put這樣的操作
HashTable是同步的
2.2 HashMap類(lèi)
HashMap和HashTable類(lèi)似,不同之處在于HashMap是非同步的,并且允許null,即null value和null key,但是將HashMap視為Collection時(shí),其迭子操作時(shí)間開(kāi)銷(xiāo)和HahMap的容量成比例。因此,如果迭代操作的性能相當(dāng)重要的話,不要將HashMap的初始化容量設(shè)的過(guò)高,或者load factor過(guò)低
2.3 WeakHashMap類(lèi)
WeakHashMap是一種改進(jìn)的HashMap,他對(duì)key實(shí)行弱引用,如果一個(gè)key不再被外部所引用,那么該key可以被GC回收