LinkedList簡介
LinkedList 是一個繼承於AbstractSequentialList的雙向鏈表。它也可以被當作堆棧、隊列或雙端隊列進行操作。
LinkedList 實現 List 接口,能對它進行隊列操作。
LinkedList 實現 Deque 接口,即能將LinkedList當作雙端隊列使用。
LinkedList 實現了Cloneable接口,即覆蓋了函數clone(),能克隆。
LinkedList 實現java.io.Serializable接口,這意味着LinkedList支持序列化,能通過序列化去傳輸。
LinkedList 是非同步的。
LinkedList相對於ArrayList來說,是可以快速添加,刪除元素,ArrayList添加刪除元素的話需移動數組元素,可能還需要考慮到擴容數組長度。
LinkedList繼承體系
LinkedList源碼分析
屬性
LinkedList本身的屬性比較少,主要有三個,一個是size,表名當前有多少個節點;一個是first代表第一個節點;一個是last代表最後一個節點。
構造方法
- 無參構造
默認構造方法是空的,什麼都沒做,表示初始化的時候size爲0,first和last的節點都爲空:
- 帶Collection集合的構造
執行邏輯:
1、使用this()調用默認的無參構造函數。
2、調用addAll()方法,傳入當前的節點個數size,此時size爲0,並將collection對象傳遞進去
3、檢查index有沒有數組越界的嫌疑
4、將collection轉換成數組對象a
5、循環遍歷a數組,然後將a數組裏面的元素創建成擁有前後連接的節點,然後一個個按照順序連起來。
6、修改當前的節點個數size的值
7、操作次數modCount自增1.
源碼如下:
addAll方法:
add方法
- add(E e)方法
實際上就是調用在尾部添加元素的方法
- add(int index,E element )方法
指定位置往數組鏈表中添加元素
1、檢查添加的位置index 有沒有小於等於當前的長度鏈表size,並且要求大於0
2、如果是index是等於size,那麼直接往鏈表的最後面添加元素,相當於調用add(E e)方法
3、如果index不等於size,則先是索引到處於index位置的元素,然後在index的位置前面添加新增的元素。
get方法
- getFirst方法
返回第一個節點元素
- getLast方法
返回最後一個結點元素
remove方法
- remove()方法
remove()方法本質是調用removeFirst方法,刪除第一個結點
- remove(int index)方法
刪除指定位置的結點。先是檢查移除的位置是否在鏈表長度的範圍內,如果不在則拋出異常,根據索引index獲取需要移除的節點,將移除的節點置空,讓其上一個節點和下一個節點對接起來。
unlink方法:
- remove(Object o)方法
刪除鏈表中的指定結點
- removeFirst()方法
移除鏈表中的第一個結點。將第一個節點置空,讓下一個節點變成第一個節點,鏈表長度減1,修改次數加1,返回移除的第一個節點。
- removeLast()方法
移除最後一個節點,將最後一個節點置空,最後一個節點的上一個節點變成last節點,,鏈表長度減1,修改次數加1,返回移除的最後一個節點。
set方法
set方法不修改modCount值。
clear方法
將所有鏈表元素置空,然後將鏈表長度修改成0,修改次數加1
toArray方法
創建一個Object的數組對象,然後將所有的節點都添加到Object對象中,返回Object數組對象。
listIterator方法
這個方法返回的是一個內部類ListIterator,用戶可以使用這個內部類變量當前的鏈表元素,但是由於LinkedList也是非線程安全的類,所以和ArrayList中的 Iterator一樣,多線程下面使用,也可能會產生多線程修改的異常。
小結
LinkedList 是雙向列表。
- 鏈表批量增加,是靠for循環遍歷原數組,依次執行插入節點操作。對比ArrayList是通過System.arraycopy完成批量增加的。增加一定會修改modCount。
- 通過下標獲取某個node 的時候,(add select),會根據index處於前半段還是後半段 進行一個折半,以提升查詢效率
- 刪也一定會修改modCount。 按下標刪,也是先根據index找到Node,然後去鏈表上unlink掉這個Node。 按元素刪,會先去遍歷鏈表尋找是否有該Node,如果有,去鏈表上unlink掉這個Node。
- 改也是先根據index找到Node,然後替換值。改不修改modCount。
- 查本身就是根據index找到Node。
- 所以它的CRUD操作裏,都涉及到根據index去找到Node的操作。