LinkedList是什麼?
* Doubly-linked list implementation of the {@code List} and {@code Deque} * interfaces. Implements all optional list operations, and permits all * elements (including {@code null}).
LinkedList是實現List和Deque的雙向鏈表,可以作爲隊列或者雙端隊列,非線程安全。
/** * Constructs an empty list. */ public LinkedList() { } /** * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's * iterator. * * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ public LinkedList(Collection<? extends E> c) { this(); addAll(c); }
LinkedList可以直接將一個ArrayList添加到一個隊列裏面。
LinkedList的變量屬性很簡單size(集合長度)、first(頭節點),last(尾節點)。其添加方法除了add()、addAll()還有addFirst(),addLast()。
我們重點看一下addAll的源碼操作:
public boolean addAll(int index, Collection<? extends E> c) { //檢查添加位置是否越界,只能在[0,size]區間添加 checkPositionIndex(index); //添加的Collection轉爲數組 Object[] a = c.toArray(); int numNew = a.length; if (numNew == 0) return false; Node<E> pred, succ; if (index == size) { //從集合最後插入數據 succ = null; pred = last; } else { //從集合中間插入數據 找到index位置的當前對象 succ = node(index); pred = succ.prev; } //遍歷數組按隊列形式插入集合 for (Object o : a) { @SuppressWarnings("unchecked") E e = (E) o; Node<E> 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; //操作次數+1 modCount++; return true; }
remove數據主要操作步驟查詢到要刪除的數據,將該數據的前一個對象和後一個對象綁在一起:
/** * Removes the element at the specified position in this list. Shifts any * subsequent elements to the left (subtracts one from their indices). * Returns the element that was removed from the list. * * @param index the index of the element to be removed * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} */ public E remove(int index) { //檢查移除數據的索引是否在[0,size)區間內 checkElementIndex(index); //查找當前位置對象 return unlink(node(index)); }
/** * Unlinks non-null node x. */ E unlink(Node<E> x) { // assert x != null; final E element = x.item; final Node<E> next = x.next; final Node<E> 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; }
LinkedList的插入刪除操作大同小異:先找到、再關聯前後對象。
在內存中,鏈表不是按順序存放的,而是通過指針連在一起,爲了訪問某一元素,必須從鏈頭開始順着指針才能找到某一個元素。
與ArrayList比較:
- 數據結構不同,ArrayList是數組結構,LinkedList是鏈表結構;
- ArrayList查詢數據比LinkedList快,在內存中數組爲連續的內存塊,而鏈表是靠指針連接的,後者在查詢時需要移動指針從一端到另一端[0,size>>1)或者[size>>1,size)去查詢;
- 添加和刪除數據時,ArrayList需要移動數據,LinkedList效率高
- 兩者都是非線程安全的,Vector是線程安全的