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); } }