概述
相較於 arraylist,linkedlist 在平時使用少一些。
linkedlist 內部是乙個雙向鍊錶,並且實現了 list 介面和 deque 介面,因此它也具有 list 的操作以及雙端佇列和棧的性質。雙向鍊錶的結構如下:
前文分析了 queue 和 deque 介面,正是因為 linkedlist 實現了 deque 介面。linkedlist 的繼承結構如下:
結點類 node
檢視 linkedlist 的原始碼可發現它內部有個巢狀類 node,**如下:
privatelinkedlist 是雙向鍊錶的實現,而該 node 類則是鍊錶的結點。static
class node
}
此外,linkedlist 還有幾個成員變數如下:
//構造器linkedlist 有兩個構造器,如下:list 的長度
transient
int size = 0;
//煉表頭結點
transient nodefirst;
//鍊錶尾結點
transient nodelast;
publicps: 由於鍊錶的容量可以一直增加,因此沒有指定容量的構造器。linkedlist()
public linkedlist(collection extends e>c)
其中第乙個為無參構造器;第二個為使用指定的集合構造,並呼叫 addall(),繼續跟進該方法,**如下:
public其中 node(index) 方法為獲取指定位置的結點,**如下:boolean addall(collection extends e>c)
public
boolean addall(int index, collection extends e>c)
else
//迴圈將陣列中的元素插入到鍊錶
for(object o : a)
//若插入到末尾,則陣列中的最後乙個元素就是尾結點
if (succ == null
) else
size +=numnew;
modcount++;
return
true
;}
nodenode(int該方法通過遍歷鍊錶獲取指定的元素。index)
else
}
值得注意的是,該方法並非直接從頭到尾遍歷整個鍊錶,而是先判斷下標的位置,若在前一半則從前往後遍歷;否則就從後往前遍歷。這樣能減少遍歷結點的個數。
ps: 前文「資料結構與演算法筆記(一)」對鍊錶進行過分析,由於其記憶體空間非連續,因此不支援隨機訪問(下標訪問)。所以,查詢某個結點是通過遍歷整個鍊錶來實現的。
與此同時,get(index) 方法內部也是這樣實現的:
public e get(int常用方法之前分析 queue 和 deque 的時候提到:queue 中的方法在 deque 中都有對應的。下面簡單分析 linkedlist 中一些常用的方法。index)
新增結點方法:add(), addlast(), offerlast()
public可以看到他們都是呼叫了同乙個方法 linklast(e) 實現的,如下:boolean
offerlast(e e)
public
void
addlast(e e)
public
boolean
add(e e)
void該操作就是將指定的結點新增到鍊錶末尾。linklast(e e)
刪除結點方法:poll(), pollfirst(), removefirst()
public可以看到這三個方法都是呼叫 unlinkfirst() 方法實現的,其**如下:e poll()
public
e pollfirst()
public
e removefirst()
private e unlinkfirst(nodef)該方法的操作就是從鍊錶頭部移除乙個結點。
向單鏈表插入和刪除結點的操作示意圖如下(雙鏈錶比這裡多了前驅結點):
棧的入棧(push)和出棧(pop)操作:
public可以看到這兩個方法直接呼叫了雙端佇列的實現方法。即,該棧是乙個「鏈式棧」。void
push(e e)
public
e pop()
執行緒安全性
執行緒安全的概念不再贅述。分析以下場景:
若有執行緒 t1 對 linkedlist 進行遍歷,同時執行緒 t2 對其進行結構性修改。
對 linkedlist 的遍歷是通過 listiterator(index) 方法實現的,如下:
public listiteratorlistiterator(int該類的 next(), add(e) 等方法在執行時會檢測 modcount 與建立時是否一致(checkforcomodification() 方法),從而判斷是否有其他執行緒對該物件進行了結構修改,若有則丟擲 concurrentmodificationexception 異常。index)
private
class listitr implements listiterator
public
e next()
public
void
remove()
//...
//是否有其他執行緒對當前物件進行結構修改
final
void
checkforcomodification()
}
因此,linkedlist 是執行緒不安全的。
小結
1. linkedlist 內部是「雙向鍊錶」,同時實現了 list 介面和 deque 介面,因此也具備 list、雙端佇列和棧的性質;
2. 執行緒不安全。
stay hungry, stay foolish.
spring原始碼分析 spring原始碼分析
1.spring 執行原理 spring 啟動時讀取應用程式提供的 bean 配置資訊,並在 spring 容器中生成乙份相應的 bean 配置登錄檔,然後根據這張登錄檔例項化 bean,裝配好 bean 之間的依賴關係,為上 層應用提供準備就緒的執行環境。二 spring 原始碼分析 1.1spr...
思科VPP原始碼分析(dpo機制原始碼分析)
vpp的dpo機制跟路由緊密結合在一起。路由表查詢 ip4 lookup 的最後結果是乙個load balance t結構。該結構可以看做是乙個hash表,裡面包含了很多dpo,指向為下一步處理動作。每個dpo都是新增路由時的乙個path的結果。dpo標準型別有 dpo drop,dpo ip nu...
redux原始碼分析(三) 原始碼部分
下面是每個部分的一些解讀 createstore apicreatestore reducer,initialstate enhancer 曾經非常好奇這個函式的第二個引數到底是initialstate還是enhancer,因為見過兩種寫法都有的,以為是版本問題。看了原始碼才發現,都可以的。如果你不...