public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{...}複製代碼
transient int size = 0;
/**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
transient Node<E> first;
/**
* Pointer to last node.
* Invariant: (first == null && last == null) ||
* (last.next == null && last.item != null)
*/
transient Node<E> last;
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;
}
}
複製代碼
Node是雙向鏈表節點所對應的數據結構,包括的屬性是:當前節點的值,上一個節點,下一個節點。java
public LinkedList() {
}
//接收一個Collection參數c,調用第一個構造方法,並把c中全部元素添加到鏈表中
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}複製代碼
經常使用方法node
LinkList遍歷不用for循環,由於用迭代器iterator遍歷比for快。數組
for循環遍歷:bash
for(int i=0; i<list.size(); i++) {
list.get(i);
}複製代碼
//LinkedList的get方法源碼
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}複製代碼
迭代器遍歷:數據結構
List<Integer> list = new LinkedList<>();
Iterator<Integer> iterator = list.listIterator();
while (iterator.hasNext()) {
Integer i = iterator.next();
}複製代碼
//next方法
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}複製代碼
從源碼能夠看出,LinkedList若是用for循環遍歷,get方法裏面會再次使用循環遍歷鏈表,時間複雜度是O(n²);若是有迭代器遍歷,由於next的存在,獲得當前項不須要時間,因此只須要使用一次循環,時間複雜度是O(n)。ui
參考資料:this