public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
繼承了bstractSequentialList類,實現了List、Deque、Cloneable、Serializable接口。
底層數據結構是鏈表,增刪快,查詢慢。先進後出,雙向鏈表。重寫了clone方法(只是淺拷貝,不會克隆鏈表中的元素)。添加的元素是能夠重複的。
字段和構造方法:
1 //被transient修飾的字段,不會被加入序列化 2 transient int size = 0; 3 4 /** 5 * Pointer to first node.第一個節點的指針 6 * Invariant: (first == null && last == null) || 7 * (first.prev == null && first.item != null) 8 */ 9 transient Node<E> first; 10 11 /** 12 * Pointer to last node. 指向最後一個節點的指針 13 * Invariant: (first == null && last == null) || 14 * (last.next == null && last.item != null) 15 */ 16 transient Node<E> last; 17 18 /** 19 * Constructs an empty list. 20 */ 21 public LinkedList() { 22 } 23 24 /** 25 * Constructs a list containing the elements of the specified 26 * collection, in the order they are returned by the collection's 27 * iterator. 28 * 29 * @param c the collection whose elements are to be placed into this list 30 * @throws NullPointerException if the specified collection is null 31 */ 32 public LinkedList(Collection<? extends E> c) { 33 this(); 34 addAll(c); 35 }
LinkedList數據結構中鏈表的本質操做:java
1 /** 2 * Links e as first element. 3 * 連接e做爲第一個元素 4 */ 5 private void linkFirst(E e) { 6 //first原先是一個空的節點 7 final Node<E> f = first;//first:第一個節點的指針 8 /** 9 * Node(Node<E> prev, E element, Node<E> next) 10 * @param prev 前一個節點 也叫前置節點 11 * @param element 當前節點上的元素 12 * @param next 下一個節點 也叫後置節點 13 */ 14 //建立一個沒有前置節點,而且當前節點的值爲e,而且後置節點爲f的節點Node 15 final Node<E> newNode = new Node<>(null, e, f); 16 //將建立的newNode節點賦給第一個節點的指針first 17 first = newNode; 18 //若是後置節點爲空,則也將newNode賦給最後一個節點的指針last;若是後置節點不爲空,則將newNode做爲 後置節點的前置節點,從而讓鏈表鏈接起來 19 if (f == null) { 20 last = newNode; 21 } 22 else { 23 f.prev = newNode; 24 } 25 size++;//鏈表的長度+1 26 modCount++;//鏈表被修改的次數+1 27 } 28 29 /** 30 * Links e as last element. 31 * 連接e做爲最後一個元素 32 */ 33 void linkLast(E e) { 34 final Node<E> l = last;//last:最後一個節點的指針 35 /** 36 * Node(Node<E> prev, E element, Node<E> next) 37 * @param prev 前一個節點 38 * @param element 當前節點上的元素 39 * @param next 下一個節點 40 */ 41 //建立一個沒有後置節點,前置節點爲l,當前節點指針指向的值爲e的節點newNode 42 final Node<E> newNode = new Node<>(l, e, null); 43 last = newNode; 44 if (l == null) { 45 //若是前置節點爲空,則將該節點做爲第一個節點的指針 46 first = newNode; 47 } 48 else { 49 //若是前置節點不爲空,則將newNode做爲 前置節點的的後置節點 50 l.next = newNode; 51 } 52 size++;//鏈表的長度+1 53 modCount++;//鏈表被修改的次數+1 54 } 55 56 /** 57 * 在非空節點succ以前插入節點e 58 * Inserts element e before non-null Node succ. 59 */ 60 void linkBefore(E e, Node<E> succ) { 61 // assert succ != null; 62 //獲取節點succ原先的前置節點 63 final Node<E> pred = succ.prev; 64 //建立一個節點newNode,該節點的前置節點爲 節點succ的前置節點,該節點的後置節點爲succ 65 final Node<E> newNode = new Node<>(pred, e, succ); 66 //將succ節點的前置節點指向newNode節點 67 succ.prev = newNode; 68 if (pred == null) { 69 //若是succ節點原先的前置節點爲空,則說明succ節點是第一個節點,則將newNode節點設置爲第一個節點 70 first = newNode; 71 } else { 72 //若是succ節點原先的前置節點不爲空,則將newNode節點做爲succ節點的 原先的節點 的後置節點。 73 pred.next = newNode; 74 } 75 size++;//鏈表的長度+1 76 modCount++;//鏈表被修改的次數+1 77 } 78 79 /** 80 * Unlinks non-null first node f. 81 * 斷開非空第一個節點f的連接。斷開以後變成兩個鏈表了。 82 * 從節點f的右側斷開。 83 * 從節點f的位置開始斷開,並將節點f指針指向的值設置爲空,而且將節點f的後置節點設置爲空。 84 * 返回節點f指針指向的值。 85 */ 86 private E unlinkFirst(Node<E> f) { 87 // assert f == first && f != null; 88 final E element = f.item; 89 //獲取節點f原先的後置節點 90 final Node<E> next = f.next; 91 f.item = null; 92 f.next = null; // help GC 93 //將節點f原先的後置節點做爲第一個節點(的指針) 94 first = next; 95 if (next == null) { 96 //若是節點f原先的後置節點爲null,說明節點f原先就是最後一個節點,將最後一個節點置爲null。 97 last = null; 98 }else { 99 //若是節點f原先的後置節點不爲null,則將節點f原先的後置節點的 前置節點置爲null,從而讓鏈表斷開。 100 next.prev = null; 101 } 102 size--;//鏈表的長度+1 103 modCount++;//鏈表被修改的次數+1 104 return element; 105 } 106 107 /** 108 * Unlinks non-null last node l. 109 * 斷開非空的最後一個節點l。 110 * 從節點l的左側斷開。斷開以後變成兩個鏈表了。 111 */ 112 private E unlinkLast(Node<E> l) { 113 // assert l == last && l != null; 114 final E element = l.item; 115 final Node<E> prev = l.prev; 116 l.item = null; 117 l.prev = null; // help GC 118 last = prev; 119 if (prev == null) 120 first = null; 121 else 122 prev.next = null; 123 size--; 124 modCount++; 125 return element; 126 } 127 128 /** 129 * Unlinks non-null node x. 130 * 斷開非空節點x的連接。至關於去掉節點x 131 */ 132 E unlink(Node<E> x) { 133 // assert x != null; 134 //節點x的指針所指向的值 135 final E element = x.item; 136 //節點x的後置節點 137 final Node<E> next = x.next; 138 //節點x的後置節點 139 final Node<E> prev = x.prev; 140 141 if (prev == null) { 142 //若是節點x原先的前置節點爲空,則說明節點x就是第一個節點,則將節點x原先的後置節點做爲第一個節點 143 first = next; 144 } else { 145 //若是節點x原先的前置節點不爲空,則將節點x的後置節點 做爲 節點x原先的前置節點的 後置節點,並將節點x的前置節點置爲null 146 prev.next = next; 147 x.prev = null; 148 } 149 150 if (next == null) { 151 //若是節點x原先的後置節點爲空,說明節點x就是最後一個元素,則將節點x原先的前置節點做爲最後一個節點 152 last = prev; 153 } else { 154 //若是節點x原先的後置節點不爲空,則將節點x原先的前置節點做爲 節點x原前後置節點的 前置節點,將節點x的後置節點置爲null 155 next.prev = prev; 156 x.next = null; 157 } 158 159 x.item = null;//將節點x指針所指向的值 置爲null 160 size--;//鏈表長度-1 161 modCount++;//鏈表被修改次數+1 162 return element;//返回節點x原先指針所指向的值 163 }
1 /** 2 * 靜態 類 Node<E> 節點 這個類做爲節點Node 3 * @param <E> 4 */ 5 private static class Node<E> { 6 E item;//當前節點的的指針指向的值 7 Node<E> next;//下一個節點的指針 8 Node<E> prev;//前一個節點的指針 9 10 /** 11 * 構造方法 Node(Node<E> prev, E element, Node<E> next) 12 * @param prev 前一個節點 13 * @param element 當前節點(指針)上的元素 14 * @param next 下一個節點 15 */ 16 Node(Node<E> prev, E element, Node<E> next) { 17 this.item = element;//將element賦值給當前節點item 將element做爲爲當前節點的指針指向的值 18 this.next = next;//將next賦給下一個節點 爲後置節點初始化 19 this.prev = prev;//將prev賦給前一個節點 爲前置節點初始化 20 } 21 }
添加:node
1 /** 2 * Inserts the specified element at the beginning of this list. 3 * 在鏈表的開始處插入元素e 4 * @param e 被插入的元素e 5 */ 6 public void addFirst(E e) { 7 linkFirst(e); 8 } 9 10 /** 11 * Appends the specified element to the end of this list. 12 * 在鏈表的末尾追加元素e 13 * <p>This method is equivalent to {@link #add}. 14 * 15 * @param e the element to add 16 */ 17 public void addLast(E e) { 18 linkLast(e); 19 } 20 21 22 /** 23 * Appends all of the elements in the specified collection to the end of 24 * this list, in the order that they are returned by the specified 25 * collection's iterator. The behavior of this operation is undefined if 26 * the specified collection is modified while the operation is in 27 * progress. (Note that this will occur if the specified collection is 28 * this list, and it's nonempty.) 29 * 30 * @param c collection containing elements to be added to this list 31 * @return {@code true} if this list changed as a result of the call 32 * @throws NullPointerException if the specified collection is null 33 */ 34 public boolean addAll(Collection<? extends E> c) { 35 return addAll(size, c); 36 } 37 38 /** 39 * Inserts all of the elements in the specified collection into this 40 * list, starting at the specified position. Shifts the element 41 * currently at that position (if any) and any subsequent elements to 42 * the right (increases their indices). The new elements will appear 43 * in the list in the order that they are returned by the 44 * specified collection's iterator. 45 * 46 * @param index index at which to insert the first element 47 * from the specified collection 48 * @param c collection containing elements to be added to this list 49 * @return {@code true} if this list changed as a result of the call 50 * @throws IndexOutOfBoundsException {@inheritDoc} 51 * @throws NullPointerException if the specified collection is null 52 */ 53 public boolean addAll(int index, Collection<? extends E> c) { 54 checkPositionIndex(index); 55 56 Object[] a = c.toArray(); 57 int numNew = a.length; 58 if (numNew == 0) 59 return false; 60 61 Node<E> pred, succ; 62 if (index == size) { 63 succ = null; 64 pred = last; 65 } else { 66 succ = node(index); 67 pred = succ.prev; 68 } 69 70 for (Object o : a) { 71 @SuppressWarnings("unchecked") E e = (E) o; 72 Node<E> newNode = new Node<>(pred, e, null); 73 if (pred == null) 74 first = newNode; 75 else 76 pred.next = newNode; 77 pred = newNode; 78 } 79 80 if (succ == null) { 81 last = pred; 82 } else { 83 pred.next = succ; 84 succ.prev = pred; 85 } 86 87 size += numNew; 88 modCount++; 89 return true; 90 }
刪除:數組
1 /** 2 * Removes and returns the first element from this list. 移除第一個元素 3 * 4 * @return the first element from this list 返回被移除的第一個元素 5 * @throws NoSuchElementException if this list is empty 6 */ 7 public E removeFirst() { 8 final Node<E> f = first; 9 if (f == null) 10 throw new NoSuchElementException(); 11 return unlinkFirst(f); 12 } 13 14 /** 15 * Removes and returns the last element from this list. 移除最後一個元素 16 * 17 * @return the last element from this list 返回被移除的第一個元素 18 * @throws NoSuchElementException if this list is empty 19 */ 20 public E removeLast() { 21 final Node<E> l = last; 22 if (l == null) 23 throw new NoSuchElementException(); 24 return unlinkLast(l); 25 } 26 27 28 29 30 /** 31 * Removes all of the elements from this list. 32 * 清空鏈表中的全部元素(也就是清空鏈表中的全部節點(節點的item、next、prev)) 33 * The list will be empty after this call returns. 34 */ 35 public void clear() { 36 // Clearing all of the links between nodes is "unnecessary", but: 37 // - helps a generational GC if the discarded nodes inhabit 38 // more than one generation 39 // - is sure to free memory even if there is a reachable Iterator 40 for (Node<E> x = first; x != null; ) { 41 Node<E> next = x.next; 42 x.item = null; 43 x.next = null; 44 x.prev = null; 45 x = next; 46 } 47 first = last = null; 48 size = 0; 49 modCount++; 50 }
1 /** 2 * Removes and returns the first element from this list. 移除第一個元素 3 * 4 * @return the first element from this list 返回被移除的第一個元素 5 * @throws NoSuchElementException if this list is empty 6 */ 7 public E removeFirst() { 8 final Node<E> f = first; 9 if (f == null) 10 throw new NoSuchElementException(); 11 return unlinkFirst(f); 12 } 13 14 /** 15 * Removes and returns the last element from this list. 移除最後一個元素 16 * 17 * @return the last element from this list 返回被移除的第一個元素 18 * @throws NoSuchElementException if this list is empty 19 */ 20 public E removeLast() { 21 final Node<E> l = last; 22 if (l == null) 23 throw new NoSuchElementException(); 24 return unlinkLast(l); 25 }
查詢:數據結構
1 /** 2 * Returns the element at the specified position in this list. 3 * 4 * @param index index of the element to return 5 * @return 返回鏈表中指定索引位置的元素 the element at the specified position in this list 6 * @throws IndexOutOfBoundsException {@inheritDoc} 7 */ 8 public E get(int index) { 9 checkElementIndex(index); 10 return node(index).item;//返回指定節點指針所指向的值 11 } 12
/** * Returns the (non-null) Node at the specified element index.返回指定元素索引處的(非空)節點。 */ Node<E> node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) { Node<E> x = first; for (int i = 0; i < index; i++) { x = x.next; } return x; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) { x = x.prev; } return x; } }
13 14 /** 15 * Returns the first element in this list. 16 * 返回LinkedList中的第一個節點的指針所指向的值。 17 * 18 * @return 返回LinkedList中的第一個元素。 19 * @throws NoSuchElementException 若是這個鏈表爲空,則拋出這個異常 20 */ 21 public E getFirst() { 22 final Node<E> f = first; 23 if (f == null) { 24 throw new NoSuchElementException(); 25 } 26 return f.item;//返回第一個節點的指針所指向的值 27 } 28 29 /** 30 * Returns the last element in this list. 31 * 32 * @return 返回LinkedList中的最後一個節點的指針所指向的值。 33 * @throws NoSuchElementException if this list is empty 34 */ 35 public E getLast() { 36 final Node<E> l = last; 37 if (l == null) 38 throw new NoSuchElementException(); 39 return l.item;//返回最後一個節點的指針所指向的值 40 }
LinkedList做爲堆棧的時候:app
1 /** 2 * Pushes an element onto the stack represented by this list. In other 3 * words, inserts the element at the front of this list. 4 * 將元素推入此列表所表示的堆棧。換句話說,就是在此鏈表的開頭插入元素 5 * <p>This method is equivalent to {@link #addFirst}. 6 * 7 * @param e the element to push 8 * @since 1.6 9 */ 10 public void push(E e) { 11 addFirst(e); 12 } 13 14 /** 15 * Pops an element from the stack represented by this list. In other 16 * words, removes and returns the first element of this list. 17 * 從這個列表表示的堆棧中彈出一個元素,換句話說,就是移除並返回此列表的第一個元素。 18 * <p>This method is equivalent to {@link #removeFirst()}. 19 * 20 * @return the element at the front of this list (which is the top 21 * of the stack represented by this list) 22 * @throws NoSuchElementException if this list is empty 23 * @since 1.6 24 */ 25 public E pop() { 26 return removeFirst(); 27 }
set方法:替換元素ui
1 /** 2 * Replaces the element at the specified position in this list with the 3 * specified element. 4 * 將列表中指定位置的元素替換爲指定元素。 5 * 6 * @param index index of the element to replace 7 * @param element element to be stored at the specified position 8 * @return the element previously at the specified position 9 * @throws IndexOutOfBoundsException {@inheritDoc} 10 */ 11 public E set(int index, E element) { 12 checkElementIndex(index); 13 Node<E> x = node(index); 14 E oldVal = x.item; 15 x.item = element; 16 return oldVal; 17 }
將LinkedList轉爲數組:this
1 /** 2 * 3 * @return 返回鏈表中按照順序排列的一個數組 4 */ 5 public Object[] toArray() { 6 Object[] result = new Object[size]; 7 int i = 0; 8 //遍歷鏈表中的全部節點,而且將節點所指向的值存放到數組中 9 for (Node<E> x = first; x != null; x = x.next) { 10 result[i++] = x.item; 11 } 12 return result; 13 }
序列化和反序列化:spa
/** * Saves the state of this {@code LinkedList} instance to a stream (that is, serializes it). * 將鏈表的實例狀態保存到一個流中。也就是將鏈表序列化成一個流。 * @serialData The size of the list (the number of elements it * contains) is emitted (int), followed by all of its * elements (each an Object) in the proper order. */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out any hidden serialization magic s.defaultWriteObject(); // Write out size s.writeInt(size); // Write out all elements in the proper order. for (Node<E> x = first; x != null; x = x.next) s.writeObject(x.item); } /** * Reconstitutes this {@code LinkedList} instance from a stream (that is, deserializes it). * 從流中從新構造這個實例。也就是將 流反序列化成鏈表(LinkedList)實例 */ @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden serialization magic s.defaultReadObject(); // Read in size int size = s.readInt(); // Read in all elements in the proper order. for (int i = 0; i < size; i++) linkLast((E)s.readObject()); }