前言
Java集合框架:集合代表了一組對象(和數組一樣,但數組長度不能變,而集合能)。Java中的集合框架
定義了一套規範,用來表示、操作集合,使具體操作與實現細節解耦。
集合框架是一個用來代表和操縱集合的統一架構。所有的集合框架都包含如下內容:
- 接口:是代表集合的抽象數據類型。接口允許集合獨立操縱其代表的細節。在面向對象的語言,接口通常
形成一個層次。 - 實現(類):是集合接口的具體實現。從本質上講,它們是可重複使用的數據結構。
- 算法:是實現集合接口的對象裏的方法執行的一些有用的計算,例如:搜索和排序。這些算法被稱爲多態,
那是因爲相同的方法可以在相似的接口上有着不同的實現。
關於java集合框架的知識:大致可分爲Set、List和Map三種體系:
- List代表有序、重複的集合
- Set代表無序、不可重複的集合
- Map則代表具有映射關係的集合
- Java 5之後,增加了Queue體系集合,代表一種隊列集合實現。
Java集合框架主要由Collection和Map兩個根接口及其子接口、實現類組成。
集合類劃分爲兩個大的部分:一種是可以按照一定順序進行迭代訪問的集合類;一種是通過名值對的映射建
立關係進行訪問的集合類。
一、Collect接口概述
1.1 collection接口概述
- Collection接口是所有後續集合類型的一個公共抽象定義。它本身沒有一個直接的實現,更多的是各種不同
的集合類型在它的基礎上繼承了更多特殊的特性並做了一個實現。 - Collection接口裏主要定義了一些作爲集合類型比較通用的方法,比如說size, isEmpty, add, remove等。
作爲集合類型比較通用的一個定義,它主要用在一些需要比較高級別抽象的地方。比如說我們需要可以
對所有集合類型進行通用操作。
1.2 Collection接口定義的方法
(1)增加、add(E e)
返回值爲boolean(是否添加成功)。
(2)清除、clear()
除去此數組的所有操作。
(3)是否包含某一元素、contains(Object o)
如果包含返回爲true(可以用於進行if判斷),如果集合裏邊的元素爲自定義
類的話需要重寫自定類的equals方法(contains方法就是基於equals實現的)否則比較的是地址。
(4)比較此collection與指定對象是否相等、equals(Object o)
返回值爲boolean(true爲相等)。
(5)此collection是否包含某元素、isEmpty()
返回值爲boolean(true爲不包含)。
(6)獲取此collection的迭代器、iterator()
用於遍歷集合(此迭代器只能遍歷集合,不能對集合進行修改,否則會報併發
修改異常-ConcurrentModificationException)。
(7)刪除指定元素、remove(Object o)
返回值爲boolean(true表示刪除成功)。
(8)返回元素數(集合的長度)、size()
返回值爲int(集合中元素的個數)。
(9)返回此集合中所有元素的數組、toArray()
返回值是一個數組
二、Collection的子接口概述
2.1 List接口
List類型的數據結構算是我們平時接觸最多而且看起來最簡單的數據結構類型。最常用的兩種是ArrayList
和LinkedList,也就是我們常說的線性表和鏈表。
特點:有序、可重複、可爲null的序列。
- ArrayList類
內部使用數組來存儲數據,也就相當於數據結構的順序表存儲,在查詢數據上面性能好。 - LinkedList類
內部使用鏈表的形式來存儲數據,在增加和刪除數據上面性能更好。
它實現了List接口和Deque接口,說明它具有兩邊接口的特性,因此它可以當作一個雙端隊列來用,
也可以當作棧來用,並且它是以鏈表的形式來實現的,所以查詢性能差,但是增加和刪除操作性能高。 - Vertor類
跟ArrayList相比,它是線程安全的,而ArrayList是線程不安全的。底層也是用數組實現的。 - Stack類繼承Vertor類
看名字,其實就是方便模擬“棧”這種數據結構
2.2 set接口
在常用的集合類型中,HashSet, TreeSet等具體的實現往往不一樣。比如說HashSet本身的實現是引用了
HashMap作爲內部的元素。如果我們仔細檢查他們的結構實現,會發現有的類型我們也可以通過foreach的
循環來遍歷。
這是因爲他們有的在實現Set定義接口的範圍同時也繼承了實現Collection接口的部分。可以說是兩者兼有之。
在上面這些集合類型中,基於Hash表實現的主要有HashSet, LinkedHashSet。基於紅黑樹實現的有TreeSet。
特點:無順序,不可重複,至多一個null
- HashSet
不能保證元素的排列順序,加入的元素要特別注意hashCode()方法的實現。
HashSet不是同步的,多線程訪問同一步HashSet對象時,需要手工同步。
集合元素值可以是null - LinkedHashSet
LinkedHashSet類也是根據元素的hashCode值來決定元素的存儲位置,但它同時使用鏈表維護元素的次序。
與H**ashSet相比,特點**:
對集合迭代時,按增加順序返回元素。
性能略低於HashSet,因爲需要維護元素的插入順序。但迭代訪問元素時會有好性能,因爲它
採用鏈表維護內部順序。 - TreeSet
TreeSet類是SortedSet接口的實現類。因爲需要排序,所以性能肯定差於HashSet。 - EnumSet類
專爲枚舉類設計的集合類,EnumSet中的所有元素都必須是指定枚舉類型的枚舉值。
2.3 Queue接口
用於模擬隊列這種數據結構,然後該接口中聲明瞭一些基本操作的方法。例如:add、offer、remove等。
- PriorityQueue類
PriorityQueue保存隊列元素的順序並不是按照加入隊列的順序,而是按隊列元素的大小重新排序。 - Deque接口
Deque代表一個雙端隊列,可以當作一個雙端隊列使用,也可以當作“棧”來使用,
因爲它包含出棧pop()與入棧push()方法。 - ArrayDeque類爲Deque的實現類
實現了Deque接口中定義的方法,解釋跟deque差不多。
2.4 各種線性表中選擇策略
- 數組
是以一段連續內存保存數據的;隨機訪問是最快的,但不支持插入、刪除、迭代等操作。 - ArrayList與ArrayDeque
以數組實現;隨機訪問速度還行,插入、刪除、迭代操作速度一般;線程不安全。 - Vector
以數組實現;隨機訪問速度一般,插入、刪除、迭代速度不太好;線程安全的。 - LinkedList
以鏈表實現;隨機訪問速度不太好,插入、刪除、迭代速度非常快。
三、Map集合框架概述
Map接口:定義一些基本的操作,例如put(key,value), containKey(Object key)等一系列操作。
使用key、value鍵值對的形式進行訪問的集合類
3.1 Map接口概述
HashMap類和Hashtable類對比
一般使用HashMap,因爲Hashtable類是很古老的,據查都不建議用。平常我們也是用HashMap。
HashMap類是線程不安全的,而Hashtable是線程安全的。
HashMap類可以使用null作爲key和value,而Hashtable不可以。Properties類繼承Hashtable類
增加了額外的一些方法,例如:load(InputStream inStream)從屬性文件加載key-value等方法。
可以將key-value用xml文件的格式保存,可能就是跟xml文件打一些交道。LinkedHashMap類繼承HashMap類
LinkedHashMap從HashMap類繼承而來。以鏈表來維護內部順序。很多方面跟LinkedHashSet類似。
LinkedHashMap它可以記住key-value對的添加時的順序, 同時避免使用TreeMap時性能受到的影響。SortedMap接口和TreeMap實現類
類似於SortedSet及TreeSet,TreeMap也可以自定義比較器(Comparable)實現定製排序。它的額外
提供的方法也與TreeSet類似,增加了訪問第一個、前一個、後一個、最後一個key-value對的方法,並
提供了從TreeMap中提取子集的方法。TreeMap不允許null作爲key,要不然怎麼比較呢?IdentityHashMap類
與HashMap的不同在於,只有兩個key嚴格相等(key1 == key2)時,IdentityHashMap才認爲兩個
key相等;而對於普通HashMap而言,只要key1.equals(key2)且hashCode相同即可。同樣允許
null值,不能保證順序。EnumMap類
EnumMap是一個與枚舉類一起使用的Map實現。它的key必須是單個枚舉類的枚舉值。EnumMap不允許
使用null作爲key,但可作爲value。
3.2 各種map類選擇策略
- 正常情況使用HashMap,而不是Hashtable。
- 如果考慮排序,那麼考慮使用TreeMap。通常TreeMap比HashMap等在插入、刪除操作時要慢不少,
因爲它需要在底層採用紅黑樹來管理key-value對。 - 如果考慮插入時的順序,那麼使用LinkedHashMap是個不錯的選擇。
- 如果想優化垃圾回收,建議使用WeakHashMap實現類(本文未提及);要求key完全匹配(同一對象),
則使用IdentityHashMap;還有枚舉類不多說了。 - 關於null值:
Hashtable不允許key爲null,也不允許value爲null;
TreeMap與EnumMap**不允許key爲null**;
HashMap及其子類LinkedHashMap,IdentityHashMap允許key爲null。