接下來要開始手撕LinkedList
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
LinkedList 繼承自AbstractSequentialList默怨,實現(xiàn)了List Deque Cloneable 實現(xiàn)了序列化质和。
在此之前,先講解一下它所具有的內(nèi)部類Node<E>芯急,我們可以知道這個LinkedList 是用鏈表實現(xiàn)的丘跌,根據(jù)這個內(nèi)部類的實例成員可以看出這是個雙向鏈表剂邮,具有前驅(qū)結(jié)點和后繼結(jié)點距糖。
private void linkFirst(E e)
增加結(jié)點到頭結(jié)點
void linkLast(E e)
增加結(jié)點到尾部結(jié)點
void linkBefore(E e, Node<E> succ)
增加一個結(jié)點到succ之前
private E unlinkLast(Node<E> l)
刪除最后一個
E unlink(Node<E> x)
刪除指定的結(jié)點
這些事LinkedList的私有函數(shù)撤蟆,一般我們調(diào)用的是其在內(nèi)部封裝好的public方法,類似于removeFirst()
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
我們從這段代碼中可以看出它其實調(diào)用了unlinkFirst颊艳。unlinkFirst是個private方法就像上面所列舉的方法一樣茅特。我們用的所有基本操作其實全部來自于這些函數(shù)。
基本操作棋枕,我們已經(jīng)很熟了,像什么添加元素到末尾妒峦,添加元素到開頭等等重斑。
我們在這些當(dāng)中,有一個modCount實例成員變量特別突出肯骇,比如它只是增加窥浪,沒有減少。
ConcurrentModificationException()
Iterator 是工作在一個獨立的線程中笛丙,并且擁有一個 mutex 鎖漾脂。 Iterator 被創(chuàng)建之后會建立一個指向原來對象的單鏈索引表,當(dāng)原來的對象數(shù)量發(fā)生變化時胚鸯,這個索引表的內(nèi)容不會同步改變骨稿,所以當(dāng)索引指針往后移動的時候就找不到要迭代的對象,所以按照 fail-fast 原則 Iterator 會馬上拋出 java.util.ConcurrentModificationException 異常。
所以 Iterator 在工作的時候是不允許被迭代的對象被改變的坦冠。但你可以使用 Iterator 本身的方法 remove() 來刪除對象形耗, Iterator.remove() 方法會在刪除當(dāng)前迭代對象的同時維護(hù)索引的一致性。(來著網(wǎng)上的答案辙浑,我覺得這個還是比較靠譜)激涤。至于fail-fast原則,fail-fast 機(jī)制是java集合(Collection)中的一種錯誤機(jī)制判呕。當(dāng)多個線程對同一個集合的內(nèi)容進(jìn)行操作時倦踢,就可能會產(chǎn)生fail-fast事件。畢竟侠草,這個linkedList不是線程安全的辱挥。vectory為線程安全類∶吻溃或者使用Collections.synchronizedList();方法轉(zhuǎn)化般贼。
而這個觸發(fā)的條件是modCount != expectedModCount。
private class ListItr implements ListIterator<E>
這個expectedModCount是來源于這個Listltr內(nèi)部類奥吩,迭代器內(nèi)部類哼蛆。它內(nèi)部維護(hù)了這個對象,這個對象的時候霞赫,expectedModCount==modCount一般是相等的腮介。
這些代碼重復(fù)的使用了內(nèi)部類,實現(xiàn)了隱藏你不想讓別人知道的操作端衰,也即封裝性叠洗。內(nèi)部類其實還有很多的用處,就留給讀者去探索了旅东。