最近在準備java基礎知識的總結,發現對於集合類的知識點不少很雜,借鑑網上的帖子,整理以下。java
集合框架是爲表示和操做集合而規定的一種統一的標準的體系結構,在java中的集合框架主要分爲兩部分:Collection接口和Map接口。算法
1.數據結構分類數組
1)線性表是在內存中數據的一種組織、存儲的方式;一維數組、順序表、鏈表、棧、隊列,循環隊列、散列表等結構是邏輯上的概念,是一種理念與思想,是屬於線性表中的一種邏輯實現。安全
2)Java中數據結構涉及到了數組(一維、多維)、順序表(ArrayList、Vector)、鏈表(LinkedArrayList、LinkedSet)、棧(stack)、隊列(Queue)、散列表(HashMap)、樹(TreeSet、TreeMap)等數據結構
1.集合框架主要實現類框架
2.集合框架類圖異步
1)Collection是最基本的集合接口,一個Collection表明一組Object,即Collection的元素(Elements)。一些Collection容許相同的元素而另外一些不行,一些能排序而另外一些不行。Java SDK不提供直接繼承自Collection的類,Java SDK提供的類都是繼承自Collection的「子接口」如List和Set。函數
2)全部實現Collection接口的類都必須提供兩個標準的構造函數:無參數的構造函數用於建立一個空的Collection,有一個Collection參數的構造函數用於建立一個新的Collection,這個新的Collection與傳入的Collection有相同的元素。後一個構造函數容許用戶複製一個Collection。性能
3)爲何繼承Iterable接口而不繼承Iterator?測試
由於Iterator接口的核心方法next()或者hasNext()是依賴於迭代器的當前迭代位置的。 若是Collection直接實現Iterator接口,勢必致使集合對象中包含當前迭代位置的數據(指針),當集合在不一樣方法間被傳遞時,因爲當前迭代位置不可預置,那麼next()方法的結果會變成不可預知。 除非再爲Iterator接口添加一個reset()方法,用來重置當前迭代位置。 但即便這樣,Collection也只能同時存在一個當前迭代位置,而Iterable則否則,每次調用都會返回一個從頭開始計數的迭代器。 多個迭代器是互不干擾的。
不一樣的Collection接口的子接口的實現類返回的Iterator具體類型可能不一樣,Array可能返回ArrayIterator,Set可能返回 SetIterator,Tree可能返回TreeIterator,可是它們都實現了Iterator接口。所以,客戶端不關心究竟是哪一種 Iterator,它只須要得到這個Iterator接口便可,這就是面向對象的威力。
1.List接口
List是有序的Collection,使用此接口可以精確的控制每一個元素插入的位置。用戶可以使用索引(元素在List中的位置,相似於數組下標)來訪問List中的元素,這相似於Java的數組。和下面要提到的Set不一樣,List容許有相同的元素。除了具Collection接口必備的iterator()方法外,List還提供一個listIterator()方法,返回一個ListIterator接口,和標準的Iterator接口相比,ListIterator多了一些add()之類的方法,容許添加,刪除,設定元素,還能向前或向後遍歷。實現List接口的經常使用類有LinkedList,ArrayList,Vector和Stack。
1)ArrayList
ArrayList實現了可變大小的數組,它容許全部元素,包括null。size,isEmpty,get,set方法運行時間爲常數。可是add方法開銷爲分攤的常數,添加n個元素須要O(n)的時間,其餘的方法運行時間爲線性。
每一個ArrayList實例都有一個容量(Capacity),即用於存儲元素的數組的大小,這個容量可隨着不斷添加新元素而自動增長,可是增加算法並無定義。當須要插入大量元素時,在插入前能夠調用ensureCapacity方法來增長ArrayList的容量以提升插入效率。和LinkedList同樣,ArrayList也是非同步的(unsynchronized)。
2)LinkedList
LinkedList實現了List接口,容許null元素。此外LinkedList提供額外的get,remove,insert方法在LinkedList的首部或尾部。這些操做使LinkedList可被用做堆棧(stack),隊列(queue)或雙向隊列(deque),能夠認爲LinkedList在方法和邏輯上和ArrayList是同樣的,只是在性能上有必定的區別,ArrayList適合隨機訪問LinkedList更適合插入和刪除,在對性能沒有很大要求是是能夠忽略這個差異的。
注意LinkedList沒有同步方法。若是多個線程同時訪問一個List,則必須本身實現訪問同步。一種解決方法是在建立List時構造一個同步的List:
List list = Collections.synchronizedList(new LinkedList(...));
3)Vector
Vector很是相似ArrayList,可是Vector是同步的。由Vector建立的Iterator,雖然和ArrayList建立的Iterator是同一接口,可是,由於Vector是同步的,當一個Iterator被建立並且正在被使用,另外一個線程改變了Vector的狀態(例如,添加或刪除了一些元素),這時調用Iterator的方法時將拋出ConcurrentModificationException,所以必須捕獲該異常。
ArrayList 和Vector是採用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增長和插入元素,都容許直接序號索引元素,可是插入數據要設計到數組元素移動等內存操做,因此索引數據快插入數據慢,Vector因爲使用了synchronized方法(線程安全)因此性能上比ArrayList要差,LinkedList使用雙向鏈表實現存儲,按序號索引數據須要進行向前或向後遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入數度較快!
4)Stack
Stack繼承自Vector,實現一個後進先出的堆棧。Stack提供5個額外的方法使得Vector得以被看成堆棧使用。基本的push和pop方法,還有peek方法獲得棧頂的元素,empty方法測試堆棧是否爲空,search方法檢測一個元素在堆棧中的位置。Stack剛建立後是空棧。
2.Set接口
Set是一種不包括重複元素的Collection。它維持它本身的內部排序,因此隨機訪問沒有任何意義。與List同樣,它一樣運行null的存在可是僅有一個。因爲Set接口的特殊性,全部傳入Set集合中的元素都必須不一樣,同時要注意任何可變對象,若是在對集合中元素進行操做時,致使e1.equals(e2)==true,則一定會產生某些問題。實現了Set接口的集合有:EnumSet、HashSet、TreeSet。
1)HashSet
HashSet堪稱查詢速度最快的集合,由於其內部是以HashCode來實現的。它內部元素的順序是由哈希碼來決定的,因此它不保證set 的迭代順序,特別是它不保證該順序恆久不變。
2)TreeSet
基於TreeMap,生成一個老是處於排序狀態的set,內部以TreeMap來實現。它是使用元素的天然順序對元素進行排序,或者根據建立Set 時提供的Comparator進行排序,具體取決於使用的構造方法。
3)LinkedHashSet
底層是鏈表實現的,是set集合中惟一一個能保證怎麼存就怎麼取的集合對象,由於是HashSet的子類,因此也是保證元素惟一的,與HashSet的原理同樣。
3.Queue接口
1)阻塞式隊列(BlockingQueue):隊列滿了之後再插入元素則會拋出異常,主要包括ArrayBlockQueue、PriorityBlockingQueue、LinkedBlockingQueue。
2)雙端隊列(Deque):支持在頭、尾兩端插入和移除元素,主要包括:ArrayDeque、LinkedBlockingDeque、LinkedList。
Map與List、Set接口不一樣,它是由一系列鍵值對組成的集合,提供了key到Value的映射。同時它也沒有繼承Collection。在Map中它保證了key與value之間的一一對應關係。也就是說一個key對應一個value,因此它不能存在相同的key值,固然value值能夠相同。實現map的有:HashMap、TreeMap、Hashtable、Properties、EnumMap。
1)HashMap
HashMap和Hashtable相似,不一樣之處在於HashMap是非同步的,而且容許null,即null value和null key。,可是將HashMap視爲Collection時(values()方法可返回Collection),其迭代子操做時間開銷和HashMap的容量成比例。所以,若是迭代操做的性能至關重要的話,不要將HashMap的初始化容量設得太高,或者load factor太低。
2)TreeMap
鍵以某種排序規則排序,內部以red-black(紅-黑)樹數據結構實現,實現了SortedMap接口
3)Hashtable
Hashtable繼承Dictionary類實現Map接口,實現一個key-value映射的哈希表。任何非空(non-null)的對象均可做爲key或者value。添加數據使用put(key,value),取出數據使用get(key),這兩個基本操做的時間開銷爲常數。
Hashtable經過initial capacity和load factor兩個參數調整性能。一般缺省的load factor 0.75較好地實現了時間和空間的均衡。增大load factor能夠節省空間但相應的查找時間將增大,這會影響像get和put這樣的操做。Hashtable是同步的。
1.Vector和ArrayList
1)vector是線程同步的,因此它也是線程安全的,而arraylist是線程異步的,是不安全的。若是不考慮到線程的安全因素,通常用arraylist效率比較高。
2)若是集合中的元素的數目大於目前集合數組的長度時,vector增加率爲目前數組長度的100%,而arraylist增加率爲目前數組長度的50%.如過在集合中使用數據量比較大的數據,用vector有必定的優點。
3)若是查找一個指定位置的數據,vector和arraylist使用的時間是相同的,都是0(1),這個時候使用vector和arraylist均可以。而若是移動一個指定位置的數據花費的時間爲0(n-i)n爲總長度,這個時候就應該考慮到使用linklist,由於它移動一個指定位置的數據所花費的時間爲0(1),而查詢一個指定位置的數據時花費的時間爲0(i)。
4)ArrayList 和Vector是採用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增長和插入元素,都容許直接序號索引元素,可是插入數據要設計到數組元素移動等內存操做,因此索引數據快插入數據慢,Vector因爲使用了synchronized方法(線程安全)因此性能上比ArrayList要差,LinkedList使用雙向鏈表實現存儲,按序號索引數據須要進行向前或向後遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入數度較快!
2.Aarraylist和Linkedlist
1)ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。
2)對於隨機訪問get和set,ArrayList以爲優於LinkedList,由於LinkedList要移動指針。
3)對於新增和刪除操做add和remove,LinedList比較佔優點,由於ArrayList要移動數據。
4)這一點要看實際狀況的。若只對單條數據插入或刪除,ArrayList的速度反而優於LinkedList。但如果批量隨機的插入刪除數據,LinkedList的速度大大優於ArrayList. 由於ArrayList每插入一條數據,要移動插入點及以後的全部數據。
3.HashMap與TreeMap
1)HashMap經過hashcode對其內容進行快速查找,而TreeMap中全部的元素都保持着某種固定的順序,若是你須要獲得一個有序的結果你就應該使用TreeMap(HashMap中元素的排列順序是不固定的)。HashMap中元素的排列順序是不固定的)。
2)HashMap經過hashcode對其內容進行快速查找,而TreeMap中全部的元素都保持着某種固定的順序,若是你須要獲得一個有序的結果你就應該使用TreeMap(HashMap中元素的排列順序是不固定的)。集合框架」提供兩種常規的Map實現:HashMap和TreeMap (TreeMap實現SortedMap接口)。
3)在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。但若是您要按天然順序或自定義順序遍歷鍵,那麼TreeMap會更好。使用HashMap要求添加的鍵類明肯定義了hashCode()和 equals()的實現。 這個TreeMap沒有調優選項,由於該樹總處於平衡狀態。
4.Hashtable與HashMap
1)歷史緣由:Hashtable是基於陳舊的Dictionary類的,HashMap是Java 1.2引進的Map接口的一個實現 。
2)同步性:Hashtable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的 。
3)值:只有HashMap可讓你將空值做爲一個表的條目的key或value 。
1.對List的選擇
1)對於隨機查詢與迭代遍歷操做,數組比全部的容器都要快。因此在隨機訪問中通常使用ArrayList。
2)LinkedList使用雙向鏈表對元素的增長和刪除提供了很是好的支持,而ArrayList執行增長和刪除元素須要進行元素位移。
3)對於Vector而已,咱們通常都是避免使用。
4)將ArrayList當作首選,畢竟對於集合元素而已咱們都是進行遍歷,只有當程序的性能由於List的頻繁插入和刪除而下降時,再考慮LinkedList。
2.對Set的選擇
1)HashSet因爲使用HashCode實現,因此在某種程度上來講它的性能永遠比TreeSet要好,尤爲是進行增長和查找操做。
2)雖然TreeSet沒有HashSet性能好,可是因爲它能夠維持元素的排序,因此它仍是存在用武之地的。
3.對Map的選擇
1)HashMap與HashSet一樣,支持快速查詢。雖然HashTable速度的速度也不慢,可是在HashMap面前仍是稍微慢了些,因此HashMap在查詢方面能夠取代HashTable。
2)因爲TreeMap須要維持內部元素的順序,因此它一般要比HashMap和HashTable慢。