前言
Java集合框架概述; 主要總述Java集合框架的設計理念, 組成和基本接口(及其區別等)
博客同步至個人博客
正文
一. 設計理念
在Java 2之前,Java是沒有完整的集合框架的。它只有一些簡單的可以自擴展的容器類,比如Vector,Stack,Hashtable等)
Java集合其實就是一組對象的集合
獨立于實現細節, 方便重用, 保證向下兼容(即保留了
Vector
等舊的API)加強了API之間的互通信, 減少了新API的學習: 提供盡量統一的接口
二. 基本組成
2.1 總述
Java集合框架主要分為三個部分: 接口, 實現和算法
2.1-1 接口
接口指的是以Collection
和Map
為起始的一系列公用接口
實際上從Map
出發的并不是真正的集合, 只是其包含集合視圖操作, 所以也將其歸入集合框架中
從Collection
出發的公用接口主要有以下幾個, 也是這次會著重講解和比較的; 當然, 下面的接口并不全面, 在后面會逐漸擴展和補充
從Map
出發的公用接口如下
當然, 上述列舉出來的子接口都是直接繼承自Collection
或者Map
, 對于其子接口的子接口, 這里并沒有列出在這里(比如NavigableMap
接口是SortedMap
接口的子接口, 而不是直接繼承Map
的, 所以這里并沒有直接列出來)
2.1-2 實現
實現指的是接口的實現類, 這里筆者在官網找到一張表, 如下, 很好的列出了平時重點所用的實現類
Interface | Hash Table | Resizable Array | Balanced Tree | Linked List | Hash Table + Linked List |
---|---|---|---|---|---|
Set | HashSet | TreeSet | LinkedHashSet | ||
List | ArrayList | LinkedList | |||
Deque | ArrayDeque | LinkedList | |||
Map | HashMap | TreeMap | LinkedHashMap |
當然, 還應該包含Java 2以前幾個舊API, 即: Vector
, Stack
, Hashtable
2.1-3 算法
(1). 算法
算法指的是以Collections
為主的提供的一系列對集合的操作, 參見下圖, 列出了其提供的常用算法
下面對上述方法進行一些簡單解釋
sort(List)
: 使用歸并排序, 保證NlogN
的時間復雜度和穩定性binarySearch(List, Object)
: 在一個有序的List
中使用二分查找reverse(List)
: 逆轉List
shuffle(List)
: 將List
中的元素隨機重排fill(List, Object)
: 使用指定值(Object
)覆蓋List
中所有元素copy(List dest, List src)
: 拷貝min(Collection)
: 返回最小值max(Collection)
: 返回最大值rotate(List list, int distance)
: 將List
中元素旋轉指定distance
replaceAll(List list, Object oldVal, Object newVal)
: 將List
中出現的所有oldVal
替換為newVal
indexOfSubList(List source, List target)
: 返回source
中與target
匹配的第一個子項的首元素索引lastIndexOfSubList(List source, List target)
: 返回最后一個匹配子項的首元素索引swap(List, int, int)
: 交換指定位置的兩個元素frequency(Collection, Object)
: 找出指定元素出現次數disjoint(Collection, Collection)
: 判斷兩個集合是否包含相同元素(即集合是否相交)addAll(Collection<? super T>, T...)
: 將指定元素添加到指定集合中
(2). 包裝類
當然, 實際上Collections
提供的不僅僅是針對集合的算法, 其還提供了一系列對集合的包裝類(即Wrapper
), 主要包括以下三大類:
Collections.unmodifiableInterface()
: 返回一個不可修改的集合, 包括UnmodifiableCollection
,UnmodifiableSet
,UnmodifiableList
; 實現原理是在修改集合的操作上(如add()
,remove()
等)拋出異常Collections.synchronizedInterface()
: 返回一個線程安全的集合, 包括SynchronizedCollection
,SynchronizedSet
,SynchronizedList
; 實現原理是在需要同步的方法上添加synchronized
限制Collections.checkedInterface()
: 返回一個類型檢查的集合, 包括CheckedCollection
,CheckedQueue
,CheckedSet
,CheckedList
; 實現原理是在add()
的時候進行類型檢查, 如果是非法類型, 就拋出異常ClassCastException
; 這里的類型檢查實際上是使用Class.isInstance()
來檢查的, 關于該方法和instanceof
運算符的區別, 參見博客; (大致上, 二者是等價的, 只是isInstance()
是在運行時才進行類型檢查, 故可用于反射, 泛型;
但是instanceof
需要在編譯時知道類的具體類型(重點理解在動態等價))
這些包裝類的作用主要是滿足平時一些特殊的需求, 比如同步, 不可修改等
三. 基本接口
在這一節, 主要講解上面提到的幾個基本接口, 這里不會涉及到其實現類
3.1 Collection
Collection
是集合框架中一個最頂層的基本接口, 提供了一個數據集的基本描述, 在官方API中并沒有提供其直接實現類, 而是在其基礎上提供了進一步的限制接口, 即List
, Set
, Queue
; 這樣做的好處有:
代碼復用: 從面向對象的角度講, 抽取出一個頂級接口, 有助于用戶代碼復用, 即編寫一個接口, 實現不同傳參(
Collection
的各種實現類), 實際上也是利用了多態(官方文檔的解釋是: 實現最大通用性)易于擴展: 符合面向對象的思想, 即將數據集抽象, 通過不同的需求對其實現不同方便的限制, 易于擴展; 同時減少新API學習成本
Collection
提供了數據操作的基本方法, 如add()
, remove()
, size()
, clear()
等; 同時, 其還繼承了Iterable
接口, 這個接口是用于使用迭代器遍歷集合用的, 使用迭代器遍歷集合的優點是我們不必知道集合的內部結果,集合的內部結構、狀態由Iterator
來維持, 通過統一的方法hasNext()
, next()
來判斷和獲取下一個元素
3.2 List
List
在Collection
上做的限制是, 元素有序(但并不是排序), 允許重復元素; 同時還將迭代器換成了ListIterator
; 關于ListIterator
, 其允許雙向的迭代, 以及元素插入(ListIterator.add()
), 刪除(ListIterator.remove()
)和替換ListIterator.set()
在JDK9
中, 還提供了一個List.of()
的靜態方法, 用于返回一個不可變List
(Immutable List
)
3.3 Set
Set
在Collection
上做的限制是, 元素不重復, 至多一個null元素
在JDK9
中, 還提供了一個Set.of()
的靜態方法, 用于返回一個不可變的Set
3.4 Queue
Queue
在Collection
上做的限制是, 除了Collection
提供的基本操作外, 還提供了一些額外的操作, 分為兩類, 一個返回特定值, 另一個拋出異常, 見下表
Throw Exception | Return Special Value | |
---|---|---|
Insert | add(e) | offer(e) |
Remove | remove() | poll() |
Examine | element() | peek() |
3.5 Map
Map
本質上是一組鍵值對, Map
允許單獨訪問key
(通過keySet()
返回key
的Set
), 也可以單獨訪問value
(通過values()
方法返回value
的Collection
), 也可以通過entrySet()
獲取key-value
的對應關系