List---Deque-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}).
List和Deque的 双向链表 实现;
LinkedList支持所有的元素,包括null;
All of the operations perform as could be expected for a doubly-linked list.
Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index.
Note that this implementation is not synchronized.
If multiple threads access a linked list concurrently, and at least one of the threads modifies the list structurally, it <i>must</i> be synchronized externally.
This is typically accomplished by synchronizing on some object that naturally encapsulates the list.
If no such object exists, the list should be "wrapped" using the {@link Collections#synchronizedList Collections.synchronizedList} method.
LinkedList是线程非同步的;
如果并发修改LinkedList,需要在外部实现同步;
可以使用Collections.synchronizedList;
The iterators returned by this class's {@code iterator} and {@code listIterator} methods are <i>fail-fast</i>: if the list is structurally modified at any time after the iterator is created, in any way except through the Iterator's own {@code remove} or {@code add} methods, the iterator will throw a {@link ConcurrentModificationException}.
Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.
LinkedList的iterator是fail-fast:
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable{ private static class Node<E> { E item; Node<E> next; Node<E> prev; } transient int size = 0; transient Node<E> first; transient Node<E> last; }
时间复杂度
get(int index):
二分查找,时间复杂度 O(log(n))
add(E e):
将新元素link到last node,时间复杂度 O(1)
remove(Object o):
从first遍历,找到相等的元素,remove,时间复杂度:O(n)
链路
add(E e)
// java.util.LinkedList.add(E) public boolean add(E e) { linkLast(e); return true; } // java.util.LinkedList.linkLast void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }
get(int index)
public E get(int index) { checkElementIndex(index); return node(index).item; } // java.util.LinkedList.node LinkedList.Node<E> node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) { // 二分查找 size>>1 = 中间位index LinkedList.Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { LinkedList.Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } }
add(int index, E element)
public void add(int index, E element) { checkPositionIndex(index); if (index == size) linkLast(element); else linkBefore(element, node(index)); // node(index):找出指定index的元素 -> linkBefore:将新元素link到old pre后、old之前; } // java.util.LinkedList.node LinkedList.Node<E> node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) { // 二分查找 size>>1 = 中间位index LinkedList.Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { LinkedList.Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } } // java.util.LinkedList.linkBefore void linkBefore(E e, LinkedList.Node<E> succ) { // assert succ != null; final LinkedList.Node<E> pred = succ.prev; final LinkedList.Node<E> newNode = new LinkedList.Node<>(pred, e, succ); succ.prev = newNode; if (pred == null) first = newNode; else pred.next = newNode; size++; modCount++; }
list.iterator()
// java.util.AbstractSequentialList.iterator public Iterator<E> iterator() { return listIterator(); } // java.util.AbstractList.listIterator() public ListIterator<E> listIterator() { return listIterator(0); } // java.util.LinkedList.listIterator public ListIterator<E> listIterator(int index) { checkPositionIndex(index); return new ListItr(index); } // java.util.LinkedList.ListItr private class ListItr implements ListIterator<E> { public boolean hasNext() { return nextIndex < size; } public E next() { checkForComodification(); if (!hasNext()) throw new NoSuchElementException(); lastReturned = next; next = next.next; nextIndex++; return lastReturned.item; } public void remove() { checkForComodification(); if (lastReturned == null) throw new IllegalStateException(); LinkedList.Node<E> lastNext = lastReturned.next; unlink(lastReturned); if (next == lastReturned) next = lastNext; else nextIndex--; lastReturned = null; expectedModCount++; } }
Collections同步链路
List<String> synchronizedList = Collections.synchronizedList(list); synchronizedList.add("aa");
Collections.synchronizedList(list)
// java.util.Collections.synchronizedList(java.util.List<T>) public static <T> List<T> synchronizedList(List<T> list) { return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<>(list) : new SynchronizedList<>(list)); } // java.util.Collections.SynchronizedList.SynchronizedList(java.util.List<E>) static class SynchronizedList<E> extends SynchronizedCollection<E> implements List<E> { final List<E> list; SynchronizedList(List<E> list) { super(list); this.list = list; } public E get(int index) { synchronized (mutex) {return list.get(index);} } public E set(int index, E element) { synchronized (mutex) {return list.set(index, element);} } public void add(int index, E element) { synchronized (mutex) {list.add(index, element);} } public E remove(int index) { synchronized (mutex) {return list.remove(index);} } public int indexOf(Object o) { synchronized (mutex) {return list.indexOf(o);} } } // java.util.Collections.SynchronizedCollection static class SynchronizedCollection<E> implements Collection<E>, Serializable { final Collection<E> c; // Backing Collection final Object mutex; // Object on which to synchronize SynchronizedCollection(Collection<E> c) { this.c = Objects.requireNonNull(c); mutex = this; } public boolean add(E e) { synchronized (mutex) {return c.add(e);} } public boolean remove(Object o) { synchronized (mutex) {return c.remove(o);} } }
synchronizedList.add("aa")
// java.util.Collections.SynchronizedCollection.add public boolean add(E e) { synchronized (mutex) {return c.add(e);} }
synchronizedList.iterator()
// java.util.Collections.SynchronizedCollection.iterator static class SynchronizedCollection<E> implements Collection<E>, Serializable { public Iterator<E> iterator() { return c.iterator(); // Must be manually synched by user! 手动实现同步 } }