Foreword
Previous analysis of the ArrayList we achieve this with an array of collections List, continue with it to analyze a relatively similar set of classes --LinkedList List today, but the underlying implementation LinkedList is a linked list, realize they have very different internal or of.
1. Overview
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable复制代码
You can see for ArrayList, LinkedList does not implement the RandomAccess interface compared to, so we know that it does not support random access. Next we look at the specific realization of LinkedList
Each list is stored first and last pointer to point to the head node and tail node:
//总节点数
transient int size = 0;
//头节点
transient Node<E> first;
//尾节点
transient Node<E> last;
复制代码
Can be found based on a doubly linked list LinkedList implementation, use the Node list node information storage.
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;
}
}复制代码
The following is a configuration diagram of a LinkedList:
2. Add
Adding a new element
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}复制代码
//尾插到尾节点并将新节点设为尾节点
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++;
}
//将新节点插入到指定节点前面
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
复制代码
3. Modify
public E set(int index, E element) {
// 检查index是否合法
checkElementIndex(index);
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}复制代码
4. Delete
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}复制代码
5. fail-fast mechanism
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
public void set(E e) {
if (lastReturned == null)
throw new IllegalStateException();
checkForComodification();
lastReturned.item = e;
}
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
Node<E> lastNext = lastReturned.next;
unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null;
expectedModCount++;
}
// fail-fast机制
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}复制代码
6. Comparison of the ArrayList
Detailed analysis of the ArrayList can look at my previous article: juejin.im/post/5d29d6...
- Based ArrayList dynamic array achieved, LinkedList Based doubly linked list;
- Set of threads are unsafe;
- Support random access ArrayList, LinkedList does not support;
- LinkedList add and delete elements in any position faster than the ArrayList.
7. Summary
- Class inheritance and implementation relationships
- Internal data structure
- Some of the more important CRUD methods
- The advantages and disadvantages of container, whether security multithreaded environment
- Comparison with a similar container for scenes, etc.