JDK1 7 LinkedList迴圈鍊錶優化

2022-10-10 12:51:08 字數 2477 閱讀 6996

最近在看jdk1.7的時候,發現linkedlist 和1.6中的變化。

首先,簡單介紹一下linkedlist:

linkedlist是list介面的雙向鍊錶實現。由於是鍊錶結構,所以長度沒有限制;而且新增/刪除元素的時候,只需要改變指標的指向(把鍊錶斷開,插入/刪除元素,再把鍊錶連起來)即可,非常方便,而arraylist卻需要重整陣列 (add/remove中間元素)。所以linkedlist適合用於新增/刪除操作頻繁的情況。

--------------------------------the code --------------------------------

在jdk 1.7之前(此處使用jdk1.6來舉例),linkedlist是通過headerentry實現的乙個迴圈鍊錶的。先初始化乙個空的entry,用來做header,然後首尾相連,形成乙個迴圈鍊錶:

在linkedlist中提供了兩個基本屬性size、header。

private transient entryheader = new entry(null, null, null);

private transient int size = 0;

其中size表示的linkedlist的大小,header表示鍊錶的表頭,entry為節點物件。

private static class entry

}

上面為entry物件的源**,entry為linkedlist的內部類,它定義了儲存的元素。該元素的前乙個元素、後乙個元素,這是典型的雙向鍊錶定義方式。

每次新增/刪除元素都是預設在鏈尾操作。對應此處,就是在header前面操作,因為遍歷是next方向的,所以在header前面操作,就相當於在鍊錶尾操作。

如下面的插入操作addbefore以及圖示,如果插入obj_3,只需要修改header.previous和obj_2.next指向obj_3即可。

private entryaddbefore(e e, entryentry)
在addbefore方法中無非就是做了這件事:構建乙個新節點newentry,然後修改其前後的引用。

在jdk 1.7,1.6的headerentry迴圈鍊錶被替換成了first和last組成的非迴圈鍊錶。

transient int size = 0;

/*** pointer to first node.

* invariant: (first == null && last == null) ||

* (first.prev == null && first.item != null)

*/transient nodefirst;

/*** pointer to last node.

* invariant: (first == null && last == null) ||

* (last.next == null && last.item != null)

*/transient nodelast;

在初始化的時候,不用去new乙個entry。

/**

* constructs an empty list.

*/public linkedlist()

在插入/刪除的時候,也是預設在鏈尾操作。把插入的obj當成newlast,掛在oldlast的後面。另外還要先判斷first是否為空,如果為空則first = obj。

如下面的插入方法linklast,在尾部操作,只需要把obj_3.next指向obj_4即可。

void linklast(e e)
其中:

1 private static class node

11 }

to sum up: 【1.6-header迴圈鍊錶】 v.s 【1.7-first/last非迴圈鍊錶】

jdk 1.7中的first/last對比以前的header有下面幾個好處:

1、  first / last有更清晰的鏈頭、鏈尾概念,**看起來更容易明白。

2、  first / last方式能節省new乙個headerentry。(例項化headerentry是為了讓後面的方法更加統一,否則會多很多header的空校驗)

3、  在鏈頭/尾進行插入/刪除操作,first /last方式更加快捷。

【插入/刪除操作按照位置,分為兩種情況:中間 和 兩頭。

在中間插入/刪除,兩者都是一樣,先遍歷找到index,然後修改鍊錶index處兩頭的指標。

在兩頭,對於迴圈鍊錶來說,由於首尾相連,還是需要處理兩頭的指標。而非迴圈鍊錶只需要處理一邊first.previous/last.next,所以理論上非迴圈鍊錶更高效。恰恰在兩頭(鏈頭/鏈尾) 操作是最普遍的】

(對於遍歷來說,兩者都是鍊錶指標迴圈,所以遍歷效率是一樣的。)

jdk原始碼閱讀 linkedlist

首先還是從建構函式開始 constructs an empty list.public linkedlist 是乙個空的 然後我們從add看 public boolean add e e 定位到linklast void linklast e e 觀察發現這個node是乙個雙向鍊錶,每乙個節點指著自...

JDK原始碼系列 LinkedList

linkedlist是乙個雙向鍊錶,實現了list和deque介面。這意味著linkedlist可以用作列表 佇列 棧 雙端佇列。transient int size 0 大小 transient node first 頭指標 transient node last 尾指標 private stat...

JDK原始碼之LinkedList

下文帶 為原始碼注釋 為個人注釋。源 使用這個顏色 構建乙個空列表 無參構造器 public linkedlist 將要新增的元素放到node物件中的item屬性中。多個node物件構成乙個鍊錶,物件中持有下乙個 和上乙個node物件 private static class node 指向最後乙個...