java集合類LinkList是數(shù)據(jù)結(jié)構(gòu)鏈表的實現(xiàn)

這次是自己閱讀JDK源碼得到的一些頓悟痊乾,java集合類LinkList是數(shù)據(jù)結(jié)構(gòu)鏈表的實現(xiàn)皮壁。

LinkedList繼承了AbstractSequentiaList,主要實現(xiàn)了接口List里的方法。

public class LinkedListextends AbstractSequentialListimplements List, Deque, Cloneable, java.io.Serializable

鏈表頭節(jié)點:

transient? Node first;

鏈表表尾節(jié)點:

transient? Node last;

1.1添加節(jié)點

使用前插法創(chuàng)建鏈表:每添加一個節(jié)點哪审,都會在當(dāng)前的鏈表頭部添加一個節(jié)點蛾魄,然后添加之后的節(jié)點成為這個鏈表的頭部---(先進(jìn)為尾,后進(jìn)為頭)湿滓。

public void addFirst(E e) {? ??

linkFirst(e);

}

private void linkFirst(E e) {

final Node f = first;? ??

final Node newNode =new Node<>(null, e, f);??

? first = newNode;? ?

?if (f ==null)? ? ??

? ? ? ?last = newNode;? ?

?else? ? ??

? ? ? ? ? ?f.prev = newNode;??

? size++;??

? modCount++;}

使用后插法創(chuàng)建鏈表:當(dāng)有節(jié)點添加進(jìn)鏈表時滴须,都會在當(dāng)前鏈表的尾部添加該節(jié)點,鏈表add()方法默認(rèn)時鏈表的后插法叽奥。---(先進(jìn)為頭描馅,后進(jìn)為尾)。

public void addLast(E e) {??

? linkLast(e);

}

public boolean add(E e) {? ?

?linkLast(e);? ??

return true;

}

void linkLast(E e) {

final Node l = last;??

? final Node newNode =new Node<>(l, e, null);??

? ? ? ? ? ? ? ? ? ?last = newNode;??

? if (l ==null)? ? ?

? ? ? ? ? ? ? ? ? ? ? first = newNode;? ??

else? ? ? ??

? ? ? ? ? ? ? ? ? ?l.next = newNode;??

? ? ? ? ? ? ? ? ? size++;? ?

? ? ? ? ? ? ? ? ? ? modCount++;

}

1.2刪除節(jié)點---刪節(jié)點動作之前都要做判空處理而线。以免刪空鏈表導(dǎo)致程序報錯

?刪除頭節(jié)點:將當(dāng)前鏈表頭的next所指向的地址铭污,賦予給first節(jié)點。之后再將該節(jié)點的前綴賦予null膀篮。

public E removeFirst() {

final Node f = first;?

?? if (f ==null)throw new NoSuchElementException();

? ? return unlinkFirst(f);

}

private E unlinkFirst(Node f) {

// assert f == first && f != null;? ??

final E element = f.item;? ?

?final Node next = f.next;?

?? f.item =null;??

? f.next =null;?

// help GC??

? first = next;??

? if (next ==null)? ? ? ?

?last =null;??

? else? ??

? ? next.prev =null;? ?

?size--;? ?

?modCount++;? ??

return element;}

刪除鏈表尾節(jié)點:找出鏈表表尾的前綴所指向的地址嘹狞,之后就是將原先未處理的鏈表表尾所指節(jié)點的next指針置為空。達(dá)到刪除表尾元素的效果誓竿。

public E removeLast() {

final Node l = last;?

?? if (l ==null)throw new NoSuchElementException();? ?

?return unlinkLast(l);

}

private E unlinkLast(Node l) {

// assert l == last && l != null;??

? final E element = l.item;

? ? final Node prev = l.prev;??

? l.item =null;?

?? l.prev =null;?

// help GC?

?? last = prev;??

? if (prev ==null)? ?

?? ? first =null;??

? else? ? ??

? prev.next =null;? ??

size--;?

?? modCount++;??

? return element;

}

刪除特定節(jié)點:

public E remove(int index) {??

? checkElementIndex(index);??

? return unlink(node(index));

}

*刪除鏈表中的節(jié)點:包括前兩種處理磅网。是remove()方法的實現(xiàn)。獲取要刪除節(jié)點的prev所指節(jié)點和next做直接點筷屡。如果prev所指的節(jié)點為null,則表示要刪除的節(jié)點是頭結(jié)點涧偷,操作和removeFirst()相一致,如果是鏈表表尾節(jié)點毙死,操作和removeLast()相一致燎潮。非上面兩種情況,則會將的prev所指節(jié)點指向next所致的節(jié)點扼倘。

public boolean remove(Object o) {

if (o ==null) {

for (Node x = first; x !=null; x = x.next) {

if (x.item ==null) {? ? ? ? ? ? ?

?? unlink(x);? ? ? ? ? ? ??

? return true;? ? ?

?? ? ? }? ??

? ? }? ?

?}else {

for (Node x = first; x !=null; x = x.next) {

if (o.equals(x.item)) {? ?

?? ? ? ? ? ? unlink(x);? ?

?? ? ? ? ? ? return true;?

?? ? ? ? ? }? ? ? ?

?}? ??

}

return false;}

E unlink(Node x) {

// assert x != null;??

? final E element = x.item;?

?? final Node next = x.next;?

?? final Node prev = x.prev;?

?? if (prev ==null) {? ? ?

?? first = next;? ? }

else {? ?

?? ? prev.next = next;? ?

?? ? x.prev =null;? ??

}if (next ==null) {? ??

? ? last = prev;? ? }

else {??

? ? ? next.prev = prev;

? ? ? ? x.next =null;? ?

?}? ?

?x.item =null;?

?? size--;? ?

?modCount++;? ??

return element;

}

1.3添加所有節(jié)點:使用一個過度節(jié)點newNode來組裝該鏈表确封。

public boolean addAll(Collection c) {return addAll(size, c);}

public boolean addAll(int index, Collection c) {? ??

checkPositionIndex(index);? ?

?Object[] a = c.toArray();? ?

?int numNew = a.length;? ?

?if (numNew ==0)return false;??

? Node pred, succ;??

? if (index == size) {? ?

?? ? succ =null;? ? ?

?? pred = last;

? ? }else {?

?? ? ? succ = node(index);? ??

? ? pred = succ.prev;? ?

?}

for (Object o : a) {? ?

?? ? @SuppressWarnings("unchecked") E e = (E) o;?

?? ? ? Node newNode =new Node<>(pred, e, null);? ?

?? ? if (pred ==null)? ? ??

? ? ? first = newNode;? ? ?

?? else? ? ? ?

?? ? pred.next = newNode;? ??

? ? pred = newNode;?

?? }

if (succ ==null) {? ?

?? ? last = pred;??

? } else {? ? ?

?? pred.next = succ;?

?? ? ? succ.prev = pred;??

? }??

? size += numNew;??

? modCount++;? ?

?return true;

}

1.4修改鏈表中特定的節(jié)點:

public E set(int index, E element) {? ??

checkElementIndex(index);? ?

?Node x = node(index);??

? E oldVal = x.item;? ?

?x.item = element;??

? return oldVal;

}

1.5在特定的位置添加節(jié)點:

public void add(int index, E element) {? ??

checkPositionIndex(index);?

?? if (index == size)? ? ??

? linkLast(element);? ?

?else? ? ??

? linkBefore(element, node(index));

}

void linkBefore(E e, Node succ) {

// assert succ != null;??

? final Node pred = succ.prev;??

? final Node newNode =new Node<>(pred, e, succ);

? ? succ.prev = newNode;?

?? if (pred ==null)? ? ??

? first = newNode;? ?

?else? ?

?? ? pred.next = newNode;? ??

size++;? ??

modCount++;

}

? ? 定位節(jié)點位置:

Node node(int index) {

// assert isElementIndex(index);? ?

?if (index < (size >>1)) {??

? ? ? Node x = first;? ? ?

?? for (int i =0; i < index; i++)? ? ? ?

?? ? x = x.next;? ??

? ? return x;? ??

}else {? ? ??

? Node x = last;? ?

?? ? for (int i = size -1; i > index; i--)? ?

?? ? ? ? x = x.prev;??

? ? ? return x;? ? }}

1.6獲取特定節(jié)點信息:

public E get(int index) {? ? checkElementIndex(index);? ? return node(index).item;}

1.7清空鏈表信息:

public void clear() {

// Clearing all of the links between nodes is "unnecessary", but:??

? // - helps a generational GC if the discarded nodes inhabit? ??

//? more than one generation??

? // - is sure to free memory even if there is a reachable Iterator?

?? for (Node x = first; x !=null; ) {? ? ??

? Node next = x.next;? ? ? ?

?x.item =null;?

?? ? ? x.next =null;??

? ? ? x.prev =null;

? ? ? ? x = next;? ?

?}??

? first = last =null;??

? size =0;? ?

?modCount++;

}

平常在工作使用的比較多的,鏈表中的add(),addAll()爪喘,remove()get()颜曾,clear()方法的具體實現(xiàn)邏輯。筆者第一次寫的博客秉剑,還有很多不足的地方泛豪,希望看過的博主們能提一提您寶貴的建議。

筆者目前是一個java小菜鳥侦鹏,還在努力學(xué)習(xí)和成長中候址。技術(shù)的進(jìn)步貴在交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末种柑,一起剝皮案震驚了整個濱河市岗仑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌聚请,老刑警劉巖荠雕,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異驶赏,居然都是意外死亡炸卑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門煤傍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盖文,“玉大人,你說我怎么就攤上這事蚯姆∥逍” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵龄恋,是天一觀的道長疙驾。 經(jīng)常有香客問我,道長郭毕,這世上最難降的妖魔是什么它碎? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮显押,結(jié)果婚禮上扳肛,老公的妹妹穿的比我還像新娘。我一直安慰自己乘碑,他們只是感情好挖息,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蝉仇,像睡著了一般旋讹。 火紅的嫁衣襯著肌膚如雪殖蚕。 梳的紋絲不亂的頭發(fā)上轿衔,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天沉迹,我揣著相機與錄音,去河邊找鬼害驹。 笑死鞭呕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宛官。 我是一名探鬼主播葫松,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼底洗!你這毒婦竟也來了腋么?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤亥揖,失蹤者是張志新(化名)和其女友劉穎珊擂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體费变,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡摧扇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了挚歧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扛稽。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖滑负,靈堂內(nèi)的尸體忽然破棺而出在张,到底是詐尸還是另有隱情,我是刑警寧澤矮慕,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布瞧掺,位于F島的核電站,受9級特大地震影響凡傅,放射性物質(zhì)發(fā)生泄漏辟狈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一夏跷、第九天 我趴在偏房一處隱蔽的房頂上張望哼转。 院中可真熱鬧,春花似錦槽华、人聲如沸壹蔓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽佣蓉。三九已至披摄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間勇凭,已是汗流浹背疚膊。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留虾标,地道東北人寓盗。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像璧函,于是被迫代替她去往敵國和親傀蚌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容