总结:
- LinkedList继承自List,具备有序性
- LinkedList继承自Deque,具备链表关联性
- LinkedList集合进行增删改查操作底层实际是操作Node节点的前后链接关系
- LinkedList进行增删操作时,仅需要操作节点的前后链接关系,因此效率较ArrayList高
- LinkedList进行查找操作时,必须从头或者从尾进行查找,因此较底层依靠数组进行存储的ArrayList查找效率低
示例代码
| public class LinkedList01 { |
| public static void main(String[] args) { |
| LinkedList linkedList = new LinkedList(); |
| linkedList.add(1); |
| linkedList.add(2); |
| linkedList.add(3); |
| linkedList.add(1 , new Intger(8)); |
| linkedList.add(5); |
| linkedList.remove(); |
| linkedList.remove(2); |
| linkedList.remove(new Integer(3)); |
| System.out.println(linkedList); |
| } |
| } |
底层代码
第1步(初始化集合)
| |
| public LinkedList() {} |
| transient int size = 0; |
| transient Node first; |
| transient Node last; |
| ... |
| |
| protected AbstractSequentialList() {} |
| ... |
| |
| protected AbstractList() {} |
| protected transient int modCount = 0; |
| ... |
| |
| protected AbstractCollection() {} |
| ... |
| |
| public Object() {} |
结果:还没有存放对象,属于空集合
第2步(往集合中添加一个元素)
| public boolean add(E e) { |
| linkLast(e); |
| return true; |
| } |
| ... |
| void linkLast(E e) { |
| final Node l = last; |
| final Node newNode = new Node<>(l, e, null); |
| last = newNode; |
| if (l == null) |
| first = newNode; |
| else |
| l.next = newNode; |
| size++; |
| modCount++; |
| } |
| ...... |
| |
| private static class Node { |
| E item; |
| Node next; |
| Node prev; |
| |
| Node(Node prev, E element, Node next) { |
| this.item = element; |
| this.next = next; |
| this.prev = prev; |
| } |
| } |
结果:集合中存放1个元素,LinkedList类中first与last属性相同,Node类中prev与next属性为null
第3步(往集合中添加第二个元素)
| public boolean add(E e) { |
| linkLast(e); |
| return true; |
| } |
| ... |
| void linkLast(E e) { |
| final Node l = last; |
| final Node newNode = new Node<>(l, e, null); |
| last = newNode; |
| if (l == null) |
| first = newNode; |
| else |
| l.next = newNode; |
| size++; |
| modCount++; |
| } |
结果:
第4步(往集合中添加第三个元素)
| public boolean add(E e) { |
| linkLast(e); |
| return true; |
| } |
| ... |
| void linkLast(E e) { |
| final Node l = last; |
| final Node newNode = new Node<>(l, e, null); |
| item属性存放当前对象 |
| last = newNode; |
| if (l == null) |
| first = newNode; |
| else |
| l.next = newNode; |
| size++; |
| modCount++; |
| } |
结果:
LinkedList添加元素流程示意图
第5步(删除集合中第一个元素)
| public E remove() { |
| return removeFirst(); |
| } |
| ... |
| public E removeFirst() { |
| final Node f = first; |
| if (f == null) |
| throw new NoSuchElementException(); |
| return unlinkFirst(f); |
| } |
| ... |
| private E unlinkFirst(Node f) { |
| |
| final E element = f.item; |
| final Node next = f.next; |
| f.item = null; |
| f.next = null; |
| first = next; |
| if (next == null) |
| last = null; |
| else |
| next.prev = null; |
| size--; |
| modCount++; |
| return element; |
| } |
第6步(根据索引来删除集合中的元素)
| public E remove(int index) { |
| checkElementIndex(index); |
| return unlink(node(index)); |
| } |
| ... |
| |
| private void checkElementIndex(int index) { |
| if (!isElementIndex(index)) |
| throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); |
| } |
| ... |
| |
| private boolean isElementIndex(int index) { |
| return index >= 0 && index < size; |
| } |
| ... |
| |
| Node node(int index) { |
| |
| if (index < (size >> 1)) { |
| Node x = first; |
| for (int i = 0; i < index; i++) |
| x = x.next; |
| return x; |
| } else { |
| Node x = last; |
| for (int i = size - 1; i > index; i--) |
| x = x.prev; |
| return x; |
| } |
| } |
| ... |
| |
| E unlink(Node x) { |
| |
| final E element = x.item; |
| final Node next = x.next; |
| final Node 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; |
| } |
第7步(根据对象内容来删除集合中的元素)
| |
| public boolean remove(Object o) { o = new Integer(3) |
| if (o == null) { |
| for (Node x = first; x != null; x = x.next) { |
| if (x.item == null) { |
| unlink(x); |
| return true; |
| } |
| } |
| } else { |
| for (Node x = first; x != null; x = x.next) { |
| if (o.equals(x.item)) { |
| unlink(x); |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
第8步(根据索引位置往集合中添加元素)
| public void add(int index, E element) { |
| checkPositionIndex(index); |
| |
| if (index == size) |
| linkLast(element); |
| else |
| linkBefore(element, node(index)); |
| } |
| ... |
| void linkLast(E e) { |
| final Node l = last; |
| final Node newNode = new Node<>(l, e, null); |
| last = newNode; |
| if (l == null) |
| first = newNode; |
| else |
| l.next = newNode; |
| size++; |
| modCount++; |
| } |
| ... |
| void linkBefore(E e, Node succ) { |
| |
| final Node pred = succ.prev; |
| final Node newNode = new Node<>(pred, e, succ); |
| succ.prev = newNode; |
| if (pred == null) |
| first = newNode; |
| else |
| pred.next = newNode; |
| size++; |
| modCount++; |
| } |