日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

容器源码分析之LinkedList(三)

發(fā)布時間:2024/2/28 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 容器源码分析之LinkedList(三) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

LinkedList的構(gòu)造方法

public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.Serializable

LinkedList實現(xiàn)了List、Deque接口,說明它有雙端隊列的特征,同時支持克隆,序列化。

我們都知道LinkedList是由鏈表實現(xiàn)的,下面是它的鏈表節(jié)點:

private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}}

LinkedList的屬性

1、LinkedList對象實例的大小

transient int size = 0;

2、頭指針:指向LinkedList中的第一個元素

transient Node<E> first;

3、尾指針:指向LinkedList中的最后一個元素

transient Node<E> last;

為什么讓node都防止序列化呢?很簡單,如果A node序列化,那么A node的下一個節(jié)點B node也要序列化,B node序列化時,B node的上一個節(jié)點A node也要序列化,這樣就陷入了無限的循環(huán)之之中,所以必須手動序列化,也就是重寫readObject和writeObject,如果還是不明白,可以參考:Effective Java之考慮自定義的序列化模式(七十五)

LinkedList的構(gòu)造方法

1、無參構(gòu)造函數(shù)

無參構(gòu)造函數(shù),即構(gòu)造一個空鏈表。

public LinkedList() {}

2、有參構(gòu)造函數(shù)

public LinkedList(Collection<? extends E> c) {this();//調(diào)用無參構(gòu)造方法構(gòu)造一個空的鏈表addAll(c);}

這里能看出來它的ArrayList的一些不同之處,它沒有默認(rèn)的大小,也沒有傳入默認(rèn)大小的參數(shù)的構(gòu)造方法,構(gòu)造方法相對簡單。

這里有個addAll(c);不著急解釋,看到后面就知道了。

Add方法

public boolean add(E e) {linkLast(e);return true;} void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);//新建一個節(jié)點last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;modCount++;}

節(jié)點鏈接再last節(jié)點之后,并處理了last節(jié)點可能為空的情況。如果為空,則first也應(yīng)該是指向這個新節(jié)點newNode

既然上面有l(wèi)inkLast,LinkedList中也有l(wèi)inkFirst(E e),方法差不多,不再贅述。還有個方法linkBefore,插入指定位置

void linkBefore(E e, Node<E> succ) {// assert succ != null;final Node<E> pred = succ.prev;final Node<E> newNode = new Node<>(pred, e, succ);succ.prev = newNode;if (pred == null)first = newNode;elsepred.next = newNode;size++;modCount++;}

LinkedList還提供了addFirst和addLast方法。如下:

public void addFirst(E e) {linkFirst(e);}public void addLast(E e) {linkLast(e);}

addFirst(E e)函數(shù)是借助于linkFirst來實現(xiàn)的,而addLast(E e)是借助于linkLast來實現(xiàn)的。add(int index,E element)添加到指定位置用LinkBefore

addAll方法

public boolean addAll(int index, Collection<? extends E> c) {checkPositionIndex(index);//索引有效性檢查,即檢查index>=0&&index<=sizeObject[] a = c.toArray();int numNew = a.length;if (numNew == 0)return false;Node<E> pred, succ;/*pred:用于表示即在此節(jié)點位置的后面插入新的節(jié)點succ:用于表示在此節(jié)點的前面位置插入節(jié)點,即插入之前此時此刻鏈表中的index位置的節(jié)點如果index==size,則在尾結(jié)點處插入否則:找到索引為index(從零開始)的位置節(jié)點*/if (index == size) {succ = null;pred = last;} else {succ = node(index);pred = succ.prev;}//將所有元素加入在pre指向之后for (Object o : a) {@SuppressWarnings("unchecked") E e = (E) o;Node<E> newNode = new Node<>(pred, e, null);//構(gòu)造新的節(jié)點if (pred == null)//如果pred為null,則說明此時加入的為第一個結(jié)點first = newNode;elsepred.next = newNode;pred = newNode;}/*在尾結(jié)點加入時,pred所指向的就是last的位置,否則,則將pred與succ的指向要進(jìn)行連接起來。*/if (succ == null) {last = pred;} else {pred.next = succ;succ.prev = pred;}size += numNew;//更改鏈表大小modCount++;//增加修改次數(shù)return true;}

方法很簡單,先找到index所在的節(jié)點,然后再這個節(jié)點的前面添加元素,如果這個節(jié)點的前面是空節(jié)點,那么這直接讓first指向集合開頭。

不知道大家都沒有發(fā)現(xiàn)LinkedList和ArrayList不同的地方,LinkedList添加一個集合modCount只加一,ArrayList的modCount加它加上的集合的大小。

其他方法

get和set方法很簡單,都是改變值的操作,相信大家不用看都應(yīng)該知道怎么寫,這里就不再贅述了

remove方法其實跟add方法類似,LinkedList同樣封裝了一個方法:unlinkFirst,unlinkLast,unlinkBefore方法,下面展示unlinkFirst方法:

private E unlinkFirst(Node<E> f) {// assert f == first && f != null;final E element = f.item;final Node<E> next = f.next;f.item = null;f.next = null; // help GCfirst = next;/*下面對next是否為空進(jìn)行分支處理;如果為空,說明鏈表為空,即應(yīng)該使得last=null;如果不為空,則將next的pre指向null。*/if (next == null) last = null;elsenext.prev = null;size--;modCount++;return element;}

remove的類似方法removeFirst,removeLast,remove(int index),remove(Object object)其實都是調(diào)用這類封裝方法。

這都是非常不錯的封裝,相比于ArrayList,它用鏈表來實現(xiàn),實現(xiàn)的思路非常清晰易懂。

總結(jié)

以上是生活随笔為你收集整理的容器源码分析之LinkedList(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。