LinkedList(Java8)個人理解
問題:對 LinkedList 的理解?
LinkedList 我將其翻譯為“連結串列”,其實也並不準確,LinkedList 實現了 List 介面和 Deque(雙端佇列) 介面,所以既可以作為連結串列(常用的方法有 add()、remove()、get())使用,也可以作為佇列(常用的方法有 offer()、poll()、peek())使用(FIFO)。並且 LinkedList 內部是雙向連結串列結構,從連結串列的任一端都可以遍歷,所以 LinkedList 還可以作為堆疊(常用的方法有 push()、pop())使用。得益於雙鏈表的結構,一個 LinkedList 有多種資料結構用途,並且對於佇列和堆疊的操作也添加了額外的方法(實際上方法內部呼叫的還是連結串列的基本方法)。
問題:LinkedList 的 Node 怎麼理解?
Node 是 LinkedList 的私有靜態內部類,作為連結串列結構的基本元素,可以看作是鏈條上的一個節(結)點。一個 node 物件中除了儲存元素的值外,還儲存著前一個 node 和後一個 node 的引用。
問題:LinkedList 內部是怎麼存放資料的?
LinkedList 對資料進行封裝,在內部組裝成 Node。LinkedList 由下面幾個部分組成,主體為若干個 Node,首尾各一個 Node 的引用,一個記錄 Node 個數的 size。前後的 Node 之間互相引用,構成雙向連結串列。如果連結串列為空,first 和 last 都指向 null,如果連結串列中只有一個 Node,first 和 last 都指向這個 Node(first 和 last 都是這個 Node 的引用)。如果連結串列有多個 Node,first 和 last 分別指向連結串列首尾的 Node。對於每個 Node 來說,如果該 Node 前還有 Node,那麼這個 Node 的 prev 指向前一個 Node,否則 prev 指向 null;如果該 Node 後還有 Node,那麼這個 Node 的 next 指向後一個 Node,否則 next 指向 null。
問題:LinkedList 是怎麼進行查詢的?
LinkedList 相比於 ArrayList 的優勢在於插入和刪除,劣勢是查詢,LinkedList 類使用雙向連結串列一定程度上確實可以提高查詢效率。
LinedList 中的查詢分為兩種,一種是根據 index 查詢 node(包含元素值),也即是 node() 方法,另一種是根據 object(元素值) 查詢 index,也即是 indexOf() 方法。連結串列不像陣列那樣,可以根據 index 直接查詢出元素的值,因為兩者在記憶體種的結構是不一樣的,陣列儲存在連續的記憶體空間,而連結串列儲存不需要連續的記憶體空間。
連結串列中的 index 只是標記元素的相對於連結串列頭部(first 指向的)node 的個數,這樣在根據 index 查詢時,可以根據 index 和 size 的關係,提高查詢效能。當 index 大致在連結串列的前半部分時(index < (size >> 1)),從連結串列的首部開始遍歷顯然更快,而當 index 大致在連結串列的後半部分時(index > (size >> 1)),從連結串列的尾部開始遍歷顯然更快,這樣就使得查詢次數從 n 次將為了 n/2 次,雖然查詢演算法的時間複雜度還是 O(n)。
根據元素值來查詢 node 的 index,使用的是 indexOf() 方法和 lastIndexOf() 方法,前一個方法是從前往後查詢,後一個方法是從後往前查詢。
問題:LinkedList 內部一些方法的區別?
LinkedList 內部有很多功能相同的方法,方法內部大多都是呼叫 link 相關的方法。
LinkedList | 新增元素 | 刪除元素 | 檢視元素 |
---|---|---|---|
作為連結串列 | add()、set() | unlink()、remove() | get() |
作為佇列 | offer() | poll() | peek() |
作為棧 | push() | pop() | 無 |
問題:LinkedList 和 ArrayList 的區別
LinkedList 是基於雙向連結串列實現的,ArrayList 是基於陣列實現的。
LinkedList 新增、插入、刪除元素速度更快,而 ArrayList 查詢速度更快。
LinkedList 使用 Node 來儲存資料,每個 Node 中不僅儲存元素的值,還儲存了前一個 Node 的引用和後一個 Node 的引用,佔用記憶體更多,而 ArrayList 使用 Object 陣列來儲存資料,佔用記憶體相比會更少。
LinkedList 和 ArrayList 都是執行緒不安全的,可以使用 Collections 中的方法在外部封裝一下。