0x00 描述
linkedlist
是乙個雙向鍊錶,這是乙個基礎的資料結構。開啟linkedlist
原始碼,可以看到它繼承於abstractsequentiallist
,這個是abstractlist
的子類。同時也實現了list
、deque
、clone
、serializable
介面。所以簡化的類關係圖可以表示為
關鍵屬性
linkedlist
是實現了序列化介面serializable
,而以上屬性都被宣告為transient
表示這些欄位不參與序列化。
節點
private
static
class
node
這個節點類,記錄鍊錶中的節點的資料,有前指標、後指標和具體的資料元素。這個資料這裡用泛型來表示了。
構造方法
public
linkedlist()
這個是預設建構函式,建立乙個空鍊錶。
public
linkedlist
(collection<
?extends
e> c)
這是通過列表來建立鍊錶的。它呼叫了addall
方法。這個方法後文會講到。
0x01 常用方法
addfirst(e e)
在鍊錶頭部新增節點
public
void
addfirst
(e e)
private
void
linkfirst
(e e)
它實際是呼叫了內部的乙個私有方法linkfirst
。只需要改變指標指向,時間複雜度o(1)。
addlast(e e)
public
void
addlast
(e e)
void
linklast
(e e)
在鍊錶尾部新增乙個節點。它也是內部的linklast
方法。這方法執行效率也很高,只需要改變指標指向,時間複雜度是o(1)。
add(e e)
public
boolean
add(e e)
可以看出也是呼叫了linklast
方法。
add(int index, e element)
public
void
add(
int index, e element)
private
void
checkpositionindex
(int index)
private
boolean
ispositionindex
(int index)
在某個index
前插入元素。
首先它會檢查index
是否正確。如果在 0~size 範圍內的下標,那麼就執行插入的方法;
它會判斷如果index
是等於size
那麼就在尾部插入元素,否則就在index
所在節點前面插入元素。
void
linkbefore
(e e, node
succ)
這個方法在節點succ
前面新增元素,時間複雜度為o(1)。
在呼叫這個方法之前需要獲取到節點
node
node
(int index)
else
}
在鍊錶中要通過下標查詢乙個節點,需要通過遍歷。這裡做了乙個優化,當index
是在前半部分時從鍊錶頭部開始遍歷;如果index
超過當前鍊錶的一半時則從後面開始遍歷查詢,它的時間複雜度為o(n)。
addall(collection extends e> c)
public
boolean
addall
(collection<
?extends
e> c)
在尾部插入乙個列表,通過呼叫add(int,collection)
來實現。
addall(int index, collection extends e> c)
public
boolean
addall
(int index, collection<
?extends
e> c)
else
//依次把陣列中的節點插入到列表中
for(object o : a)
//鏈結後向指標
if(succ == null)
else
//更新size和modcount
size += numnew;
modcount++
;return
true
;}
這個方法稍微複雜一點
先檢測index
是否有效
以陣列的形式獲取到列表資料
找到index
所在節點的前向指標,後向指標
依次把陣列中的節點插入到列表中
鏈結後向指標的資料
更新size
和modcount
get(int index)
public e get
(int index)
獲取index
所在元素,通過node
方法獲取。前面分析可以知道,這個方法需要遍歷,它的時間複雜度是o(n)。
contains(object o)
public
boolean
contains
(object o)
public
intindexof
(object o)
}else
}return-1
;}
查詢某個物件是否存在於該鍊錶中是通過遍歷來實現的。
peek()
檢視煉表頭節點
public e peek()
peekfirst()
檢視煉表頭節點
public e peekfirst()
peeklast()
檢視鍊錶尾部節點
public e peeklast()
poll()
獲取頭節點,並把頭節點從鍊錶中刪除
public e poll()
private e unlinkfirst
(node
f)
pollfirst()
同上
public e pollfirst()
polllast()
獲取尾部節點,並將尾部節點刪除
public e polllast()
private e unlinklast
(node
l)
remove()
刪除頭節點
public e remove()
public e removefirst()
clear()
清空鍊錶
public
void
clear()
first = last = null;
size =0;
modcount++
;}
遍歷整個鍊錶,將節點中的資料置為null
。
0x02 總結
JDK JDK原始碼分析 LinkedList
概述 相較於 arraylist,linkedlist 在平時使用少一些。linkedlist 內部是乙個雙向鍊錶,並且實現了 list 介面和 deque 介面,因此它也具有 list 的操作以及雙端佇列和棧的性質。雙向鍊錶的結構如下 前文分析了 queue 和 deque 介面,正是因為 lin...
原始碼閱讀 Glide原始碼閱讀之with方法(一)
前言 本篇基於4.8.0版本 原始碼閱讀 glide原始碼閱讀之with方法 一 原始碼閱讀 glide原始碼閱讀之load方法 二 原始碼閱讀 glide原始碼閱讀之into方法 三 大多數情況下,我們使用glide 就一句 但是這一句 裡面蘊含著成噸的 with方法有以下幾個過載方法 publi...
原始碼閱讀 Glide原始碼閱讀之load方法(二)
原始碼閱讀 glide原始碼閱讀之load方法 二 原始碼閱讀 glide原始碼閱讀之into方法 三 首先,load方法有以下幾個過載方法 public requestbuilder load nullable bitmap bitmap public requestbuilder load nu...