1. 程式人生 > >Java集合系列02--LinkedList

Java集合系列02--LinkedList

LinkedList

(1)LinkedList是一個繼承與AbstractSequentialList的雙向連結串列。它也可以被當做堆疊、佇列和雙向佇列使用。
(2)LinkedList實現了List介面,能對它進行佇列操作。
(3)LinkedList實現了Deque介面,即可以當做雙端佇列使用。
(4)LinkedList實現了Cloneable,即可以覆蓋clone()方法。
(5)LinkedList實現了java.io.Serializable介面,這就意味著它支援序列化,可以通過序列化去傳輸。

AbstractSequentialList簡介
AbstractSequentialList實現了add、get、remove這些函式,這些函式的介面都是隨機訪問List的,LinkedList是雙向連結串列;既然它繼承與AbstractSequentialList那麼它也就實現了這些方法。
此外,我們若需要通過AbstractSequentialList自己實現一個列表,只需要擴充套件此類,並提供 listIterator() 和 size() 方法的實現即可。若要實現不可修改的列表,則需要實現列表迭代器的 hasNext、next、hasPrevious、previous 和 index 方法即可。

LinkedList與Collection的關係圖

這裡寫圖片描述
LinkedList的本質是雙鏈表。
(1)LinkedList繼承與AbstractSequentialList並且實現了Deque介面。
(2)LinkedList包含兩個重要成員:header和size;
header是雙向連結串列的表頭,它是雙向連結串列所對應表頭類Entry的例項。Entry包括成員變數:previous、next、element。
size是表中節點的個數。

LinkedList總結

LinkedList是基於雙向連結串列實現的。既然是基於雙向連結串列實現那麼它的順序訪問速度非常快而隨機訪問速度就會慢許多。同時它也實現了List介面那麼它就實現了一些根據索引來操作連結串列的方法。它是如何將雙向連結串列和索引值聯絡起來的呢?
實現起來非常簡單,它是通過記數索引來實現的。例如remove(int index)他會比較index與size/2的大小,從而決定從連結串列的頭或尾開始尋找。
(01) LinkedList 實際上是通過雙向連結串列去實現的。
它包含一個非常重要的內部類:Entry。Entry是雙向連結串列節點所對應的資料結構,它包括的屬性有:當前節點所包含的值,上一個節點,下一個節點。
(02) 從LinkedList的實現方式中可以發現,它不存在LinkedList容量不足的問題。
(03) LinkedList的克隆函式,即是將全部元素克隆到一個新的LinkedList物件中。
(04) LinkedList實現java.io.Serializable。當寫入到輸出流時,先寫入“容量”,再依次寫入“每一個節點保護的值”;當讀出輸入流時,先讀取“容量”,再依次讀取“每一個元素”。
(05) 由於LinkedList實現了Deque,而Deque介面定義了在雙端佇列兩端訪問元素的方法。提供插入、移除和檢查元素的方法。每種方法都存在兩種形式:一種形式在操作失敗時丟擲異常,另一種形式返回一個特殊值(null 或 false,具體取決於操作)
(06) LinkedList可以作為FIFO(先進先出)的佇列。
(07) LinkedList可以作為LIFO(後進先出)的棧。

LinkedList與ArrayList的對比

(1)順序插入速度ArrayList會比較快。因為ArrayList是基於陣列實現的,陣列是事先new好的,只要往指定位置塞一個數據就好;LinkedList則不同,每次順序插入的時候都會new一個物件出來,如果物件比較大,那麼時間必然後長一點,再加上一些引用賦值的操作,所以速度必然就會慢一些。
(2)基於上面這一點,因為LinkedList裡面不僅維護了待插入的元素,還維護了Entry的前置和後繼,如果LinkedList中的Entry非常多,那麼LinkedList將比ArrayList更耗費記憶體。
(3)有人認為LinkedList做插入、刪除操作更快,這種說法並不準確:
1、LinkedList做插入、刪除的時候,慢在定址,快在只需要改變前後的Entry的引用地址。
2、ArrayList做插入、刪除時候,慢在陣列的批量copy,快在定址。

所以如果待插入、刪除的元素是資料結構的前半段,尤其是非常靠前的時候,LinkedList的效率將大大高於ArrayList,因為ArrayList將需要大量copy元素;越往後對LinkedList沒有什麼影響,但ArrayList由於批量拷貝的元素變少效率也將追上甚至超過LinkedList。
從這個分析來看,如果你十分確定你的插入、刪除元素師前半段,那麼就使用Linkedlist,否則考慮使用ArrayList。如果不確定該怎麼辦呢?那麼就建議使用Linkedlist,因為一LinkedList整體插入、刪除執行效率比較穩定,二插入元素很有可能就會帶來一次擴容,擴容是一個非常消耗時間和空間的操作。

LinkedList與ArrayList的迭代

ArrayList使用普通的for迴圈遍歷,LinkedList使用foreach迴圈比較快。
ArrayList是實現了RandomAccess介面,而LinkedList沒有實現這個介面。無論怎麼樣都不要使用普通for迴圈遍歷LinkedList其速度會慢的令人髮指。