LinkedList
1.概述
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, Serializable
- LinkedList是用双向链表实现的列表。
- LinkedList插入、删除较快,查询较慢。
- LinkedList可以存放包含null对象的任何元素。
- LinkedList是线程不安全的。
LinkedList相关类图:
2.详解
字段
1 transient Node<E> first; // 双向链表的头结点 2 transient Node<E> last; // 双向链表的尾节点 3 transient int size = 0; // 双向链表中元素个数
一些方法
1 private static class Node{ 2 E item; 3 Node next; 4 Node prev; 5 Node(Node prev, E element, Node next){ 6 this.item = element; 7 this.next = next; 8 this.prev = prev; 9 } 10 } 11 /** 12 * 把Collection中的元素依次插入到索引位置之前 13 * @param index 索引 14 */ 15 private boolean addAll(int index, Collection<? extends E> c){ 16 // 检查索引位置 17 checkPositionIndex(index); 18 19 Object[] a = c.toArray(); 20 int numNew = a.length; 21 if(numNew == 0){ 22 return false; 23 } 24 25 Node<E> pred, succ; // 定义Node的前驱与后继 26 if(index == size){ // 如果在尾部插入 27 succ = last; // 后继为尾部 28 pred = null; // 前驱为空 29 }else{ // 如果不在尾部 30 succ = node(index); // 后继就是该索引所在Node 31 pred = succ.prev; // 前驱指向前一个位置 32 } 33 for(Object o : a){ 34 @SuppressWarning("unchecked") E e = (E) o; 35 Node<E> newNode = new Node<>(pred, e, null); // 创建newNode,指定前驱,后继为null 36 if(pred == null){ 37 first = newNode; 38 }else{ 39 pred.next = newNode; 40 } 41 pred = newNode; 42 } 43 if(succ == null){ 44 last = pred; 45 } else { 46 pred.next = succ; 47 succ.prev = pred; 48 } 49 size++; 50 modCount++; 51 return true; 52 } 53 /** 54 * 该方法是返回索引所在位置的节点:index与size/2比较,若小于则从first开始查找,若大于则从last开始查找 55 */ 56 Node<E> node(int index){ 57 if(index > (size >> 1)){ 58 Node<E> x = first; 59 for(int i = 0; i < index; i++){ 60 x = x.next; 61 } 62 return x; 63 }else{ 64 Node<E> x = last; 65 for(int i = size - 1; i > index; i--){ 66 x = x.prev; 67 } 68 return x; 69 } 70 }
3.自己模仿写的LinkedList
由于实现List、Deque等接口需要实现太多的方法,我就没有实现这些接口,仅仅写点代码表示LinkedList的基本思路
1 class LinkedList<E> { 2 // LinkedList包含元素的数目 3 private int size; 4 // 头结点 5 private Node<E> first; 6 // 尾节点 7 private Node<E> last; 8 9 /** 10 * 插入头部 11 */ 12 private void linkFirst(E e){ 13 final Node<E> f = first; 14 final Node<E> newNode = new Node<>(null, e, f); 15 first = newNode; 16 if(f == null){ 17 last = newNode; 18 } else { 19 f.prev = newNode; 20 } 21 size++; 22 } 23 24 /** 25 * 插入尾部 26 */ 27 private void linkLast(E e){ 28 final Node<E> l = last; 29 final Node<E> newNode = new Node<>(l, e, null); 30 last = newNode; 31 if(l == null){ 32 first = newNode; 33 } else { 34 l.next = newNode; 35 } 36 size++; 37 } 38 39 /** 40 * 插入到某个非空结点succ之前 41 */ 42 private void linkBefore(E e, Node<E> succ){ 43 final Node<E> pred = succ.prev; 44 final Node<E> newNode = new Node<>(pred, e, succ); 45 succ.prev = newNode; 46 if(pred == null){ 47 last = newNode; 48 } else { 49 pred.next = newNode; 50 } 51 size++; 52 } 53 54 /** 55 * 删除不为空的头结点f 56 */ 57 private E unlinkFirst(Node<E> f){ 58 final E element = f.item; 59 final Node<E> next = f.next; 60 f.next = null; 61 f.item = null; // help GC 62 first = next; 63 if(next == null){ 64 last = null; 65 } else { 66 next.prev = null; 67 } 68 size--; 69 return element; 70 } 71 72 /** 73 * 删除不为空的尾节点l 74 */ 75 private E unlinkLast(Node<E> l){ 76 final E element = l.item; 77 final Node<E> prev = l.prev; 78 l.prev = null; 79 l.item = null; // help GC 80 last = prev; 81 if(prev == null){ 82 first = null; 83 } else { 84 prev.next = null; 85 } 86 size--; 87 return element; 88 } 89 90 /** 91 * 删除不为空的节点x 92 */ 93 private E unlink(Node<E> x){ 94 final E element = x.item; 95 final Node<E> prev = x.prev; 96 final Node<E> next = x.next; 97 if (prev == null) { 98 first = next; 99 } else { 100 prev.next = next; 101 x.prev = null; 102 } 103 if (next == null) { 104 last = prev; 105 } else { 106 next.prev = prev; 107 x.next = null; 108 } 109 x.item = null; //help GC 110 size--; 111 return element; 112 } 113 private static class Node<E>{ 114 Node<E> prev; 115 E item; 116 Node<E> next; 117 Node(Node<E> prev, E element, Node<E> next){ 118 this.prev = prev; 119 this.item = element; 120 this.next = next; 121 } 122 } 123 }