package java.util; //linkedlist是雙向鏈表,結構看起來是一個環,最後一個數據接到header上 public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable { //鏈表類,和hashmap同樣,你們習慣叫桶,這個桶用來存儲linkedList的全部數據 private transient Entry<E> header = new Entry<E>(null, null, null); //實際存儲的數據量 private transient int size = 0; //構造函數,初始化鏈表的第一個值 public LinkedList() { header.next = header.previous = header; } //構造函數,把實現collection接口的數據存儲入集合內,具體方法細節下面分析 public LinkedList(Collection<? extends E> c) { this(); addAll(c); } //獲取鏈表上的第一個值 public E getFirst() { //鏈表上沒值就報錯 if (size==0) throw new NoSuchElementException(); //不爲空就返回header後的第一個值(header爲此鏈表上的第一個對象,可是此對象的elements爲空) return header.next.element; } //返回鏈表上的最後一個值 public E getLast() { if (size==0) throw new NoSuchElementException(); //鏈表上的最後一個值就是header前一個值 return header.previous.element; } //移除第一個 public E removeFirst() { return remove(header.next); } //移除最後一個 public E removeLast() { return remove(header.previous); } //添加數據到第一個位置 public void addFirst(E e) { addBefore(e, header.next); } //添加數據到最後一個位置 public void addLast(E e) { addBefore(e, header); } //查看是否包含指定數據 public boolean contains(Object o) { return indexOf(o) != -1; } //返回此鏈表的大小 public int size() { return size; } //添加數據(默認添加到鏈表的末尾) public boolean add(E e) { addBefore(e, header); return true; } //移除鏈表上指定的元素 public boolean remove(Object o) { if (o==null) { //若是o爲空,則對鏈表進行循環,注意一點,在此比較的時候是用「!=」,因此比較的是內存地址,而e也確實就相 //當於一個指針,一直循環指向鏈表上的值 for (Entry<E> e = header.next; e != header; e = e.next) { if (e.element==null) { //找到值就刪除它 remove(e); return true; } } } else { //不爲空的時候就在鏈表上找到這個值,而後移除它,此時找到的是與o相等的第一個值 for (Entry<E> e = header.next; e != header; e = e.next) { if (o.equals(e.element)) { remove(e); return true; } } } return false; } //添加一個Collection到集合內 public boolean addAll(Collection<? extends E> c) { return addAll(size, c); } //上面方法的具體業務實現 public boolean addAll(int index, Collection<? extends E> c) { //index不合理就報錯 if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); //把collection轉換成數組,發現數組爲空就報錯,具體toArray()方法在AbstractCollection有實現 Object[] a = c.toArray(); int numNew = a.length; if (numNew==0) return false; modCount++; //找出兩個對象,successor是index+1處的值(index處的值實際是鏈表上index+1處的值,由於多了一個elemen //t爲空的header),predecessor 纔是index處的值 Entry<E> successor = (index==size ? header : entry(index)); Entry<E> predecessor = successor.previous; //遍歷,把數組中的值按順序添加到指定位置 for (int i=0; i<numNew; i++) { //利用構造函數建立新的對象,根據Entry的內部元素,這個構造函數就至關於在鏈表上插入數據,可是喊不夠完整 Entry<E> e = new Entry<E>((E)a[i], successor, predecessor); //把前一個數據指向下一個數據的指針移到新建立的e上面(以前是指向successor的) predecessor.next = e; //移動這個指針指向新加入的值, predecessor = e; //以上兩行代碼有區別: predecessor.next = e;修改的是predecessor.next這個元素真正在堆中的對象 //predecessor = e;這個僅僅修改的是predecessor的指向,也就至關於修改指針 //當調用對象屬相的時候就是在操做這個對象的自己了,若是隻是操做聲明,也就是棧中的值,那僅僅是修改 //這個指針,若是還不懂就本身建立個組合對象試一下就知道了 } //循環完了就把successor對象的指向前一個值的指針修改一下,從指向最初的predecessor變成傳入數組的最後 //一個值,不懂就仔細想一想,畫個圖就懂了 successor.previous = predecessor; size += numNew; return true; } //清空 public void clear() { Entry<E> e = header.next; //從header的下一個值開始循環到header,各類清空 while (e != header) { Entry<E> next = e.next; e.next = e.previous = null; e.element = null; e = next; } //清理header,結果是都變成空 header.next = header.previous = header; size = 0; modCount++; } //獲取鏈表index+1處的element public E get(int index) { return entry(index).element; } //修改指定位置的值,並返回此處原來的值,沒啥好說的 public E set(int index, E element) { Entry<E> e = entry(index); E oldVal = e.element; e.element = element; return oldVal; } //在指定位置添加值 public void add(int index, E element) { addBefore(element, (index==size ? header : entry(index))); } //移除指定位置的值 public E remove(int index) { return remove(entry(index)); } //返回鏈表上index+1處的值 private Entry<E> entry(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); Entry<E> e = header; //若是傳入的值比size/2要小,就從頭開始循環 if (index < (size >> 1)) { for (int i = 0; i <= index; i++) e = e.next; } else { //反之就從末尾開始循環 for (int i = size; i > index; i--) e = e.previous; } return e; } //找到第一個element等於o的對象,並返回此對象的位置,沒啥好說的 public int indexOf(Object o) { int index = 0; if (o==null) { for (Entry e = header.next; e != header; e = e.next) { if (e.element==null) return index; index++; } } else { for (Entry e = header.next; e != header; e = e.next) { if (o.equals(e.element)) return index; index++; } } return -1; } //找到最後一個element等於o的對象,返回此處的位置,也沒啥好說的 public int lastIndexOf(Object o) { int index = size; if (o==null) { for (Entry e = header.previous; e != header; e = e.previous) { index--; if (e.element==null) return index; } } else { for (Entry e = header.previous; e != header; e = e.previous) { index--; if (o.equals(e.element)) return index; } } return -1; } //集合沒值返回空,有值就返回第一個值的element public E peek() { if (size==0) return null; return getFirst(); } //返回第一個值的element,其實和上一個方法差很少,只不過沒值的時候上面一個返回空,這個是報錯 public E element() { return getFirst(); } //沒值返回空,有值就幹掉第一個 public E poll() { if (size==0) return null; return removeFirst(); } //幹掉第一個 public E remove() { return removeFirst(); } //添加元素到鏈表末尾 public boolean offer(E e) { return add(e); } //添加元素到鏈表的開頭 public boolean offerFirst(E e) { addFirst(e); return true; } //和add方法如出一轍,好幾個添加方法都幾乎同樣,不用深究,沒屁用 public boolean offerLast(E e) { addLast(e); return true; } //獲取第一個值,沒值返回空 public E peekFirst() { if (size==0) return null; return getFirst(); } //獲取最後一個值,沒值就返回空 public E peekLast() { if (size==0) return null; return getLast(); } //移除…………不想寫了,都一個樣 public E pollFirst() { if (size==0) return null; return removeFirst(); } public E pollLast() { if (size==0) return null; return removeLast(); } public void push(E e) { addFirst(e); } public E pop() { return removeFirst(); } //移除鏈表上第一個element等於o的對象 public boolean removeFirstOccurrence(Object o) { return remove(o); } //移除鏈表上最後一個element等於o的對象,和上一個方法想法,注意此處調用的remove,上個方法的remove在以前有封 //裝,本質和這個方法同樣,只是指針的順序變成倒敘,可是上個方法的remove傳入的參數是object,這個remove傳入的 //參數是Entry,可是最終的業務類是同樣,重載了一遍而已 public boolean removeLastOccurrence(Object o) { if (o==null) { for (Entry<E> e = header.previous; e != header; e = e.previous) { if (e.element==null) { remove(e); return true; } } } else { for (Entry<E> e = header.previous; e != header; e = e.previous) { if (o.equals(e.element)) { remove(e); return true; } } } return false; } public ListIterator<E> listIterator(int index) { return new ListItr(index); } //實現迭代器,具體還沒看·· private class ListItr implements ListIterator<E> { private Entry<E> lastReturned = header; private Entry<E> next; private int nextIndex; private int expectedModCount = modCount; ListItr(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); if (index < (size >> 1)) { next = header.next; for (nextIndex=0; nextIndex<index; nextIndex++) next = next.next; } else { next = header; for (nextIndex=size; nextIndex>index; nextIndex--) next = next.previous; } } public boolean hasNext() { return nextIndex != size; } public E next() { checkForComodification(); if (nextIndex == size) throw new NoSuchElementException(); lastReturned = next; next = next.next; nextIndex++; return lastReturned.element; } public boolean hasPrevious() { return nextIndex != 0; } public E previous() { if (nextIndex == 0) throw new NoSuchElementException(); lastReturned = next = next.previous; nextIndex--; checkForComodification(); return lastReturned.element; } public int nextIndex() { return nextIndex; } public int previousIndex() { return nextIndex-1; } public void remove() { checkForComodification(); Entry<E> lastNext = lastReturned.next; try { LinkedList.this.remove(lastReturned); } catch (NoSuchElementException e) { throw new IllegalStateException(); } if (next==lastReturned) next = lastNext; else nextIndex--; lastReturned = header; expectedModCount++; } public void set(E e) { if (lastReturned == header) throw new IllegalStateException(); checkForComodification(); lastReturned.element = e; } public void add(E e) { checkForComodification(); lastReturned = header; addBefore(e, next); nextIndex++; expectedModCount++; } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } //鏈表類,沒啥,就倆指針 private static class Entry<E> { E element; Entry<E> next; Entry<E> previous; Entry(E element, Entry<E> next, Entry<E> previous) { this.element = element; this.next = next; this.previous = previous; } } //在entry這個值以前添加e private Entry<E> addBefore(E e, Entry<E> entry) { Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); //修改指針的指向 newEntry.previous.next = newEntry; newEntry.next.previous = newEntry; size++; modCount++; return newEntry; } //剛纔說的移除方法 private E remove(Entry<E> e) { if (e == header) throw new NoSuchElementException(); //舊的數據存儲起來,而後準備返回,修改指針指向 E result = e.element; e.previous.next = e.next; e.next.previous = e.previous; //清空e e.next = e.previous = null; e.element = null; size--; modCount++; //返回原來的值 return result; } public Iterator<E> descendingIterator() { return new DescendingIterator(); } private class DescendingIterator implements Iterator { final ListItr itr = new ListItr(size()); public boolean hasNext() { return itr.hasPrevious(); } public E next() { return itr.previous(); } public void remove() { itr.remove(); } } //克隆方法,返回鏈表的淺表副本,也就是隻有這個對象的內存地址不一樣,內部的屬性的內存地址與被克隆的一致 public Object clone() { LinkedList<E> clone = null; try { clone = (LinkedList<E>) super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } clone.header = new Entry<E>(null, null, null); clone.header.next = clone.header.previous = clone.header; clone.size = 0; clone.modCount = 0; for (Entry<E> e = header.next; e != header; e = e.next) clone.add(e.element); return clone; } //轉成數組 public Object[] toArray() { Object[] result = new Object[size]; int i = 0; for (Entry<E> e = header.next; e != header; e = e.next) result[i++] = e.element; return result; } //轉換成指定類型的數組 public <T> T[] toArray(T[] a) { if (a.length < size) a = (T[])java.lang.reflect.Array.newInstance( a.getClass().getComponentType(), size); int i = 0; Object[] result = a; for (Entry<E> e = header.next; e != header; e = e.next) result[i++] = e.element; //若是傳入的數組比此鏈表的長度要長,則把數組上緊挨着鏈表最後一個元素給清除,數組上後續的值仍然保留,並未移 //除或者修改 if (a.length > size) a[size] = null; return a; } private static final long serialVersionUID = 876323262645176354L; private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { s.defaultWriteObject(); s.writeInt(size); for (Entry e = header.next; e != header; e = e.next) s.writeObject(e.element); } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); int size = s.readInt(); header = new Entry<E>(null, null, null); header.next = header.previous = header; for (int i=0; i<size; i++) addBefore((E)s.readObject(), header); } }