集合原始碼分析之 LinkedList

2021-10-12 07:33:30 字數 4769 閱讀 3451

glinkedlist底層時基於鍊錶結構

linkedlist內部結構及屬性

public class linkedlistextends abstractsequentiallistimplements list, deque, cloneable, serializable 

}

建構函式解析

鍊錶裡面只有乙個first和last,其他的元素通過node物件的next和prev進行出串聯

public linkedlist(collection extends e> c)

//新增集合到linkedlist中

public boolean addall(int index, collection extends e> c) else

//迴圈要插入的集合

for (object o : a)

if (succ == null) else

size += numnew;

modcount++;

return true;

}//node方法實現

nodenode(int index) else

}

//根據位置獲取鍊錶元素位置

public e get(int index)

//通過二分法查詢index所在鍊錶的位置

//頭部查詢從first開始

//尾部查詢從last開始

default nodenode(int index) else

}

set

//往index位置,replaces替換元素

public e set(int index, e element)

1、首先從鍊錶的角度來講,鍊錶插入是很快的,只需要移動鍊錶node裡面的prev和next位置即可,但是陣列就不一樣還得需要system.copy底層拷貝,將陣列元素進行移動才得行

--替換思路

1、檢查要替換的index是否在鍊錶size範圍內(index>=0 && indexadd

//在index位置插入新元素

public void add(int index, e element)

//插入思路

1、首先要檢查要插入的位置是否在0-size之間(含0和size)如果等於size意思就是在鍊錶最後追加乙個元素

情況1,加入index==size時,加入鍊錶最後

(1)首先判斷鍊錶last是否==null

--是,直接將first=last=element,然後將size=1;modcount++

linklast

--加入last為空,則當前這個節點設定為first。否則將last.next = new新的節點

linkbefore

--否,找打index所在鍊錶的node元素

----通過二分法查詢node,node方法之前已經詳細分析過了

----然後將element放到index位置,如何放?

原來index的node位置=node(index)

node oldnode = node(index);

oldnode.prev = element;將舊的node的上乙個元素設定為element

然後將element.next = oldnode;將elment的下乙個元素設定為oldnode(這些動作在new node的時候已經完成)

--源**:

找打要插入節點的原節點的上乙個元素(記錄起來)

然後new新節點,將新節點的上乙個節點設定為原節點的上乙個節點;(那麼原節點的上乙個節點,就要設定為新節點succ.prev = newnode)

====下面看看原始碼

void linkbefore(e e, nodesucc)

//上面linkbefore做了那麼多事情,關鍵思路就是

1、需要把新的插入節點給new出來,然後把上乙個節點的next分情況,設定為新插入的節點node

2、原節點的prev節點的next要設定為newnode,如果原節點prev為null時,那麼說明插入位置就是fisrt

3、然後調整原節點原節點的prev要設定為新節點

//index=size

void linklast(e e)

remove

//刪除鍊錶中的index位置的節點

public e remove(int index)

checkelementindex

檢查index在0-size之間(含0),可以理解為陣列元素位置

unlink實現思考

自己理解

node oldnode = node(index);//要刪除的節點

進行鍊錶操作

node oldnodeprev = oldnode.prev;//要刪除的鍊錶的上乙個節點

node oldnodenext = oldnode.next;//要刪除的鍊錶的下乙個節點

如果oldnodeprev==null表示移除的鍊錶第乙個節點first

fisrt = oldnodenext;//將要刪除的鍊錶的下乙個節點設定為fisrt(思路一致)

如果oldnodeprev!=null

oldnodeprev.next = oldnodenext;//思路一致

--將原刪除鍊錶的上乙個節點設定為oldnodeprev

oldnodenext.prev = oldnodeprev;

如果oldnodenext ==null那麼

last= oldnodeprev ;

如果oldnodenext !=null那麼

===源**怎麼說

e unlink(nodex) else

if (next == null) else

x.item = null;//gc work

size--;

modcount++;

return element;

}

一些基本操作

//獲取乙個元素

public e getfirst()

public e getlast()

//移除乙個節點

public e removefirst()

//unlinkfirst思路思考

1、將first的next取出來

2、將next作為first

private e unlinkfirst(nodef)

//移除最後乙個節點

public e removelast()

//private e unlinklast(nodel)

小結:1、鍊錶底層就是對node-prev和next進行設定

2、每次操作基於size然後取nodex

3、根據first和last判斷要正向遍歷處理還是逆向

public void addfirst(e e)

private void linkfirst(e e)

//public void addlast(e e)

//void linklast(e e)

//查詢引數節點在鍊錶的位置(0開始計算)

public int indexof(object o)

} else

}return -1;

}//lastindexof由鍊錶逆向遍歷,取prev

public int lastindexof(object o)

} else

}return -1;

}//peek沒有就返回null

public e peek()

//如果為空時,要拋異常

public e element()

//檢索,並刪除鍊錶的第乙個元素(這個有點類似於佇列取元素)--從頭部開始取

public e poll()

//刪除第乙個節點,如果為空,拋異常的

public e remove()

//deque介面--queue佇列介面(為了讓linkedlist具有deque的功能)

//指定的元素新增為linkedlist的最後乙個元素

public boolean offer(e e)

//取出乙個節點並刪除

public e pop()

//public t toarray(t a)

list總結:

可以重複,通過索引取出加入資料,順序與插入順序一致,可以含有null元素

arraylist:底層資料結構使陣列結構array,查詢速度快,增刪改慢,因為是一種類似陣列的形式進行儲存,因此它的隨機訪問速度極快;

vector:底層是陣列結構array,與arraylist相同,查詢速度快,增刪改慢;

linkedlist:底層使用鍊錶結構,增刪速度快,查詢稍慢;

arraylist與vector的區別:

1.如果集合中的元素數量大於當前集合陣列的長度時,vector的增長率是目前陣列長度的100%,而arryalist增長率為目前陣列長度的50%。所以,如果集合中使用資料量比較大的資料,用vector有一定優勢

2.執行緒同步arraylist是執行緒不同步,所以vector執行緒安全,但是因為每個方法都加上了synchronized,所以在效率上小於arraylist

集合原始碼分析之 Map AbstractMap

抽象map 定義抽象方法entryset,交給子類實現 這樣抽象類就可以使用此方法,做一些預設實現。但是entryset由具體的子類實現 public abstract set entryset 看看hashmap entryset實現 例如 獲取集合元素個數 public int size pub...

原始碼分析集合Hashmap

public v put k key,v value final v putval int hash,k key,v value,boolean onlyifabsent,boolean evict 如果鍊錶中有相同的key直接跳出迴圈 if e.hash hash k e.key key key ...

Map集合 原始碼分析

map的實現類的結構 map 雙列資料,儲存key value對的資料 hashmap 作為map的主要實現類 執行緒不安全的,效率高 可以儲存null和key的value hashmap的底層 陣列 鍊錶 jdk7之前 陣列 鍊錶 紅黑樹 jdk8 linkedhashmap 保證在遍歷map元素...