前些天花了12篇博客,分析了Java
常用的容器的源碼,主要是List、Queue、Map、Set等接口的實現類。此篇博客將對這些容器進行一個總結,但不會涉及源碼,如果需要了解更多的細節,可以通過文中的鏈接閱讀。
Java常用容器JDK源碼分析總結目錄
一、Java容器
概述
在Java語言中,主要有四種類型的容器,分別爲List
、Queue
、Map
、Set
。但是這個四個只是接口,爲了方便應對不同的需求,每個接口都設計了多個實現類
。List
容器的特點是智能數組式的,可隨機訪問(下標訪問),容量可自由伸縮;Queue
容器的特點是隊頭出隊
、隊尾入隊
,一般隊中間的元素不對外展示;Map
容器的特點是存放key-value
形式的數據;Set
容器的主要特點是容器中存放的元素能保持唯一性。四種接口與其實現類的繼承關係圖如下:
二、List
容器
1、ArrayList
容器
ArrayList
容器是通過封裝一個Object
數組來實現,插入
元素前判斷數組是否要擴容
,如果是插入序列中間
,還需要移動元素騰出一個空位置,刪除
元素時,需要前移元素,去掉中間的空位。此容器的特點就是隨機訪問
(下標訪問)效率高,但是移除
、插入
元素的效率低,並且不支持併發讀寫。
源碼分析博客鏈接→Java容器之ArrayList源碼分析(這應該是Java中最簡單的容器吧)
2、Vector
容器
Vector
容器底層同樣是通過數組來實現,與ArrayList
容器沒啥區別。但是Vector
容器的方法都加上了synchronized
關鍵字,也就說Vector
容器支持併發讀寫,鎖爲this對象
,即整個容器。
源碼分析博客鏈接→Java容器之Vector源碼分析(Vector容器爲啥線程安全呢?)
3、LinkedList
容器
LinkedList
容器是基於雙鏈表
實現,但是該容器仍然實現了隨機訪問
(下標訪問),把first
看成下標0,每次移動一個節點,下標加1,所以隨機訪問
的效率很低。不過由於是鏈表實現,所以刪除
元素、插入
元素效率高,並不需要騰出空位置、擴容啥的,直接修改指針的指向即可。
源碼分析博客鏈接→Java容器之LinkedList源碼分析(LinkedList到底是單鏈表還是雙鏈表?)
ArrayList
、Vector
容器都是基於數組實現,隨機訪問
效率高,插入、刪除效率低,Vector
容器支持併發讀寫,引入鎖機制,降低了容器的性能。LinkedList
容器基於雙鏈表
實現,隨機訪問
效率低,但是插入、刪除元素效率高,爲引入鎖機制,所以不支持併發讀寫。
因此如果你有大量的插入
、刪除
需求,可以考慮LinkedList
容器,如果隨機訪問
多,則可以考慮使用ArrayList
容器,如果需要併發讀寫,那隻能選擇Vector
容器。
三、Queue
容器
1、PriorityQueue
容器
PriorityQueue
容器底層是通過數組
來維護一個堆結構
,並且這個堆結構
通過數組下標
在邏輯上成立,並沒有物理實現。通過指定容器的比較器(或者將存儲的類型實現comparable
接口)可構建小頂堆
(堆頂存放容器元素的最小值)、大頂堆
(堆頂存放容器元素的最大值)。
源碼分析博客鏈接→Java容器之PriorityQueue源碼分析(附堆的調整圖解)
2、ArrayDeque
容器
ArrayDeque
容器是雙端隊列
(隊頭
、隊尾
都支持入隊
、出隊
操作,普通隊列只支持隊頭出隊
,隊尾入隊
)容器,底層通過循環數組
實現。所謂的循環數組
,就是當下標爲-1時,跳轉到數組的尾端,同樣當下標爲數組的長度時,跳轉到下標0。
源碼分析博客鏈接→Java容器之ArrayDeque源碼分析(你知道ArrayDeque維護循環數組的原理嗎?)
3、LinkedList
容器
前文在List
容器中已經分析過這個容器,由於LinkedList
既實現了List
接口,又實現了Deque
接口,所以它既是List容器,又是雙端隊列容器。這裏就不贅述了。
四、Map
容器
前面已經總結過Map
容器了,所以直接閱讀前面的博客即可,鏈接→Java中的常見五種map容器源碼分析總結(HashMap、Hashtable、ConcurrentHashMap、LinkedHashMap、TreeMap)
五、Set
容器
前面已經總結過Set
容器了,所以直接閱讀前面的博客即可,鏈接→Java容器之HashSet、LinkedHashSet、TreeSet源碼分析(不敢稱東半球最好,只稱東半球最好理解)
以上就是Java
常用容器JDK
源碼分析總結的全部內容了。看完這些容器的源碼你會發現,也就Map
容器中的TreeMap
容器、ConcurrentHashMap
容器稍微複雜一點,其它的容器的實現都比較簡單。