本章分析List系列中的LinkedList,真正意義上的鏈表,底層採用鏈表形式存儲數據元素。LinkedList是一個雙向鏈表,可以向前或向後兩個方向遍歷鏈表。LinkedList也可以存放null元素。
一、 類實現/繼承體系結構
爲了對整個List實現/繼承體系有個全貌,先將體系結構圖畫出來:
二、 關鍵數據成員
(1)節點類
private static classNode<E>,包含標準的雙向鏈表節點結構:元素、指向前一個元素的引用和指向下一個元素的引用。
(2)首尾節點
爲了更便利的操作鏈表,比如在鏈表末尾添加刪除元素,LinkedList提供了首尾兩個節點引用:
transient Node<E>first;
transient Node<E>last;
(3)鏈表存放的元素個數
transient int size = 0;
三、 構造函數
LinkedList提供了兩種形式的構造函數:
publicLinkedList ()
publicLinkedList (Collection<? extends E> c):利用另一個集合初始化LinkedList,要求就是負責初始化集合中的元素類型是E或者是E的子類。
四、 增
(1) void addFirst(E e):將值爲e的元素加入到鏈表頭部,會調用linkFirst:
private voidlinkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null,e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
(2) void addLast(E e):將值爲e的元素加入到鏈表尾部,跟addFirst類似,只是將元素加到鏈表尾部;
(3) boolean add(E e):默認加到鏈表的末尾,linkLast(e);
(4) boolean addAll(Collection<? extends E> c)與
booleanaddAll(int index, Collection<? extends E> c)都是將容器c中的元素添加到鏈表中,不帶index的接口,默認加到鏈表尾部,所以實現也是調用帶index的接口:
publicboolean addAll(Collection<? extends E> c) {
returnaddAll(size, c);
}
(5) boolean offer(E e):添加到鏈表尾部,同offerLast
(6) boolean offerFirst(E e):添加到鏈表頭部
五、 刪
(1) E removeFirst():刪除鏈表第一個元素,首先判斷first是否合法,然後調用unlinkFirst:
private EunlinkFirst(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 GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
(2) E removeLast():刪除最後一個元素,與removeFirst類似,調用unlinkLast實現刪除最後一個元素;
(3) boolean remove(Object o)
(4) public E poll():返回並刪除第一個元素;
(5) public E remove():刪除第一個元素;
(6)
六、 改
(1) E set(int index, E element):設置index位置的元素值
七、 查
(1) E getFirst():獲取第一個元素;
(2) E getLast():獲取最後一個元素;
(3) boolean contains(Object o):是否包含元素o,使用indexOf函數判斷,不包含返回-1;
(4) public E peek():返回第一個元素,如果鏈表爲空,返回null;
(5) public E element():返回第一個元素,如果鏈表爲空,則拋出異常NoSuchElement;
(6) public E poll()
八、 遍歷
類似於ArrayList