Java集合--List
前言:
本文基於jdk1.8,如有寫的不對的地方,歡迎指出。
這篇文章主要講List介面的三個實現類,貼圖。
在瞭解List之前最好了解一下資料結構的基礎,推薦一個公眾號Java3y,裡面有很多關於java的基礎知識,Java實現單向連結串列,棧和佇列就是這麼簡單,二叉樹就這麼簡單。
開始正題。
一:ArrayList
如圖所示為ArrayList的結構。
如果想了解ArrayList的父類及實現介面的話可以自行百度,這裡就不深入講了,接下來看看ArrayList的原始碼。
1:屬性
2:構造器
3:add(E e)方法
在增加元素時會先將陣列實際長度+1。
如果當前陣列為DEFAULTCAPACITY_EMPTY_ELEMENTDATA(空陣列),則取預設擴容大小跟實際長度+1的最大值,得到最大的容量,不浪費系統資源,如果擴容後陣列的長度大於原陣列的長度,則呼叫擴容方法grow()
oldCapacity為原陣列長度,newCapacity為原陣列擴容後的長度如果擴容後的長度無法滿足需要擴容的長度的話,就取需要擴容的長度,所以網上說的擴容1.5倍其實是不準確的。該擴容方法重點講三個點:移位運算子、最大擴容長度及copyof方法。
(1):
java中有三種移位運算子
<< : 左移運算子,num << 1,相當於num乘以2
>> : 右移運算子,num >> 1,相當於num除以2
>>> : 無符號右移,忽略符號位,空位都以0補齊
具體運算規則是轉化為二進位制數進行移位操作,相對於 oldCapacity + (oldCapacity/2)效能會好點,具體可以參考這篇文章
(2):最大擴容長度為Integer.MAX_VALUE。
(3):Arrays.copyOf()方法是java.util包下面的一個方法,具體作用是建立一個新陣列,把資料依次插入到新陣列。(由於arraycopy是java本地方法,是由c++寫的,所以這裡就不擴充套件了,有興趣的朋友可以自行百度)
另外提兩點:1:add方法是不是原子性的操作,所以是執行緒不安全的,集合工具包有提供建立執行緒安全的集合的方法List list = Collections.synchronizedList(new ArrayLIst()),具體可自行了解。2:刪除元素時不會減少容量,若希望減少容量則呼叫trimToSize()
ArrayList就講到這裡,類裡面的其他方法都比較簡單,大家可以閱讀原始碼自行了解。
二:Vector
Vector跟ArrayList的最大區別就是Vector是執行緒安全的,看原始碼,方法都是synchronized修飾的,所以犧牲了很大一部分效能,另外一點就是ArrayList在底層陣列不夠用時在原來的基礎上擴充套件0.5倍,Vector是擴充套件1倍。
三:LinkedList
如圖所示為LinkedList的結構,LinkedList實現了Deque介面,所以我們可以像操作棧喝佇列一樣操作LinkedList。
1:屬性
LinkedList就三個屬性,實際容量,頭節點跟尾節點
2:構造方法
3:add方法
就是往連結串列尾節點新增元素的操作。
LinkedList的方法太多了,這裡就不一一講解了,都比較簡單。
補充一點:
ArrayList增刪慢不是絕對的(在數量大的情況下):
如果一直使用add方法增加元素(增加到末尾)的話,那是ArrayList要快,一直刪除末尾的元素或者刪除中間位置的元素也是ArrayList要快(不涉及移位操作)。
但一般來說:增刪多還是用LinkedList,因為上面的情況是不常見。