天天看點

JDK1.7-LinkedList循環連結清單優化

 最近在看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。

 其中size表示的linkedlist的大小,header表示連結清單的表頭,entry為節點對象。

  上面為entry對象的源代碼,entry為linkedlist的内部類,它定義了存儲的元素。該元素的前一個元素、後一個元素,這是典型的雙向連結清單定義方式。

JDK1.7-LinkedList循環連結清單優化

每次添加/删除元素都是預設在鍊尾操作。對應此處,就是在header前面操作,因為周遊是next方向的,是以在header前面操作,就相當于在連結清單尾操作。

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

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

JDK1.7-LinkedList循環連結清單優化

---------------------------------------------

     在jdk 1.7,1.6的headerentry循環連結清單被替換成了first和last組成的非循環連結清單。

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

JDK1.7-LinkedList循環連結清單優化

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

obj。

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

JDK1.7-LinkedList循環連結清單優化

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,是以理論上非循環連結清單更高效。恰恰在兩頭(鍊頭/鍊尾)

操作是最普遍的】

(對于周遊來說,兩者都是連結清單指針循環,是以周遊效率是一樣的。)