java LinkedList分析(ZZ)

  1. // ZZ From :http://
  2.     // hi.baidu.com/yifan_870829/blog/item/6595fb03e0c614e908fa93f0.html
  3.          public class LinkedList<E> extends AbstractSequentialList<E>
  4.             implements List<E>, Deque<E>, Cloneable, java.io.Serializable {
  5.                  private transient Entry<E> header = new Entry<E>(nullnullnull);
  6.                  private transient int size = 0;
  7.          }      // 可以看到,LinkedList继承了抽象的序列链表类,并实现了List、Queue、Cloneable、Serializable接口,使LinkedList可以像队列一样进行操作,同时可以克隆和串行化,使其能够保存到文件。
  8.         // 值得我们注意的是,在这里面声明变量时,用到了transient关键词。那么他是什么意思啊?
  9.         // transient 关键字表示在Serializable 的时候不保存该值。这两个变量在串行化时,不需要保存。
  10.         // Entry类到底是如何实现的呢?
  11.         private static class Entry<E> {
  12.         E element;
  13.         Entry<E> next;
  14.         Entry<E> previous;
  15.         Entry(E element, Entry<E> next, Entry<E> previous) {
  16.              this.element = element;
  17.              this.next = next;
  18.              this.previous = previous;
  19.         }
  20.         }
  21.         // 可以看到了,Entry里面声明了变量elment,next和previous,这就是我们在数据结构中知道的一个节点类声明。这是一个双向链表,不是吗?
  22.         public LinkedList() {
  23.                 header.next = header.previous = header;
  24.             }
  25.         // 构造函数。初始化链表类。将next和previous指针指向自己。
  26.         public LinkedList(Collection<? extends E> c) {
  27.             this();
  28.             addAll(c);
  29.         }
  30.         // 用一个链表类初始化LinkedList,关于上面的红色部分,据我的理解,这个泛型类要求加入的泛型元素必须是E的子类。
  31.         // 这个构造函数调用了默认构造函数,addAll把c添加到LinkedList中,下面会介绍这个函数。
  32.         public E getFirst() {
  33.                if (size==0) {
  34.                    throw new NoSuchElementException();
  35.                }
  36.             return header.next.element;
  37.         }
  38.         // 返回第一个元素。如果size==0,抛出异常,否则就返回head.next.element;
  39.         // 通过这句话,我们似乎明白,这里的数据结构是有头结点的。
  40.         public E getLast() {
  41.              if (size==0) {
  42.                  throw new NoSuchElementException();
  43.              }
  44.              return header.previous.element;
  45.         }
  46.         // 返回最后一个元素。如果size==0,那么抛出异常。否则返回header.previous.element。
  47.         // 这就是双向链表,将头结点的previous指向最后一个元素。
  48.         public E removeFirst() {
  49.             return remove(header.next);
  50.         }
  51.         
  52.         public E removeLast() {
  53.            return remove(header.previous);
  54.         }
  55.         
  56.         public E remove(int index) {
  57.                 return remove(entry(index));
  58.         }
  59.         
  60.         private E remove(Entry<E> e) {
  61.             if (e == header) {
  62.                 throw new NoSuchElementException();
  63.             }
  64.             E result = e.element;
  65.             e.previous.next = e.next;
  66.             e.next.previous = e.previous;
  67.             e.next = e.previous = null;
  68.             e.element = null;
  69.             size--;
  70.             modCount++;
  71.             return result;
  72.         }
  73.         // 移走元素。要移走的元素已经确定,不需再找到这个元素。所以直接移走就可以了。先用result指向要移走的元素。然后按照数据结构中的算法移走就可以了。移走后返回移走的元素。
  74.         // modCount是在AbstractList中声明使用的。用来记录这个链表结构被修改的次数。this list has been
  75.         
  76.         public void addFirst(E e) {
  77.             addBefore(e, header.next);
  78.         }
  79.         
  80.         public void addLast(E e) {
  81.             addBefore(e, header);
  82.         }
  83.         
  84.         public boolean add(E e) {
  85.             addBefore(e, header);
  86.                 return true;
  87.         }
  88.         
  89.         public void add(int index, E element) {
  90.             addBefore(element, (index==size ? header : entry(index)));
  91.         }
  92.         
  93.         private Entry<E> addBefore(E e, Entry<E> entry) {
  94.             Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
  95.             newEntry.previous.next = newEntry;
  96.             newEntry.next.previous = newEntry;
  97.             size++;
  98.             modCount++;
  99.             return newEntry;
  100.         }
  101.         // 将元素e添加到entry前面。很简单,不用分析,相信你也明白。
  102.         
  103.         public boolean contains(Object o) {
  104.             return indexOf(o) != -1;
  105.         }
  106.         public int indexOf(Object o) {
  107.                 int index = 0;
  108.                 if (o==null) {// 如果o为null
  109.                     for (Entry e = header.next; e != header; e = e.next) {
  110.                         if (e.element==null)
  111.                             return index;
  112.                         index++;
  113.                     }
  114.                 } else {        //不为空,其判断是通过equals进行判断的。
  115.                     for (Entry e = header.next; e != header; e = e.next) {
  116.                         if (o.equals(e.element))
  117.                             return index;
  118.                         index++;
  119.                     }
  120.                 }
  121.                 return -1;
  122.             }
  123.         // 首先获得元素的索引值。如果返回-1,无这个元素。为什么要分元素是不是空这个分支呢?因为如果o是空的话,判断是通过e.element==null判断的。不为空,则通过o.equals(e.element)判断。
  124.         public int size() {
  125.         return size;
  126.             }
  127.         // 返回大小。
  128.         public boolean remove(Object o) {
  129.                 if (o==null) {
  130.                     for (Entry<E> e = header.next; e != header; e = e.next) {
  131.                         if (e.element==null) {
  132.                             remove(e);
  133.                             return true;
  134.                         }
  135.                     }
  136.                 } else {
  137.                     for (Entry<E> e = header.next; e != header; e = e.next) {
  138.                         if (o.equals(e.element)) {
  139.                             remove(e);
  140.                             return true;
  141.                         }
  142.                     }
  143.                 }
  144.                 return false;
  145.             }
  146.         // 也比较容易理解。不做解释了。
  147.         
  148.         public boolean addAll(Collection<? extends E> c) {
  149.             return addAll(size, c);
  150.         }
  151.         
  152.         public boolean addAll(int index, Collection<? extends E> c) {
  153.                 if (index < 0 || index > size)// 如果要插入的位置>size或小于0,异常。
  154.                     throw new IndexOutOfBoundsException("Index: "+index+
  155.                                                         ", Size: "+size);
  156.                 Object[] a = c.toArray();// 将集合中的元素转化为数组。
  157.                 int numNew = a.length;// 返回数组长度
  158.                 if (numNew==0)// 如果是0的话,遗憾,无法添加了
  159.                     return false;
  160.                 modCount++;// 不是0的话,ok,修改计数器加1
  161.                 Entry<E> successor = (index==size ? header : entry(index));// 如果index==size,那么successor=header
  162.                 Entry<E> predecessor = successor.previous;// 获得前一个处理元素
  163.             for (int i=0; i<numNew; i++) {// 对于数组每一个元素,生成entry类,加入到链表中。
  164.                         Entry<E> e = new Entry<E>((E)a[i], successor, predecessor);
  165.                         predecessor.next = e;
  166.                         predecessor = e;
  167.                     }
  168.                 successor.previous = predecessor;
  169.                 size += numNew;
  170.                 return true;
  171.          }
  172.         // 如上注解。
  173.         
  174.         public void clear() {
  175.                 Entry<E> e = header.next;
  176.                 while (e != header) {
  177.                     Entry<E> next = e.next;// 记录e的next
  178.                     e.next = e.previous = null;// 去掉e的next和previous
  179.                     e.element = null;// 去掉自己元素。
  180.                     e = next;// 处理下一个节点
  181.                 }
  182.                 header.next = header.previous = header;
  183.                 size = 0;
  184.                 modCount++;
  185.         }
  186.         // 将链表清空。不用解释了。很简单。不过,我们通过这个方法明白一点,要真正的销毁对象,光靠垃圾回收机制是不行的。像这里,给没有用的引用赋空值,使内存中的实体对象没有指针,而加快内存的回收。
  187.         public E get(int index) {
  188.             return entry(index).element;
  189.         }
  190.         
  191.         private Entry<E> entry(int index) {
  192.                 if (index < 0 || index >= size)
  193.                     throw new IndexOutOfBoundsException("Index: "+index+
  194.                                                         ", Size: "+size);
  195.                 Entry<E> e = header;// 获得头结点
  196.                 if (index < (size >> 1)) {// 如果index小于size的一半
  197.                     for (int i = 0; i <= index; i++)
  198.                         e = e.next;
  199.                 } else {// 不小于的话,ok,从后面找。
  200.                     for (int i = size; i > index; i--)
  201.                         e = e.previous;
  202.                 }
  203.                 return e;
  204.             }
  205.         
  206.         // 多么好的算法啊。如果要找的元素在前半部分,那就从头找,如果在最后那么就从尾开始找。获得size的一半也很节省cpu消耗,采用移位的方式,值得学习。
  207.         public E set(int index, E element) {
  208.                 Entry<E> e = entry(index);
  209.                 E oldVal = e.element;
  210.                 e.element = element;
  211.                 return oldVal;
  212.             }
  213.         // 不再解释。很简单。
  214.         
  215.         // 下面的分析关系到了LinkedList的遍历、持久化、克隆等相关主题。
  216.         public ListIterator<E> listIterator(int index) {
  217.             return new ListItr(index);
  218.         }
  219.         // 返回一个从index开始的遍历器。
  220.   private class ListItr implements ListIterator<E> {
  221.         private Entry<E> lastReturned = header;// 让这里面的参数初始化,最后一个返回的元素。
  222.         private Entry<E> next;// 下一个元素的指针
  223.         private int nextIndex;// 下一个元素的索引
  224.         private int expectedModCount = modCount;// 等于原来类中的修改次数
  225.         
  226.         ListItr(int index) {// 构造函数
  227.              if (index < 0 || index > size)// 如果给的index不正确
  228.            throw new IndexOutOfBoundsException("Index: "+index+
  229.                   ", Size: "+size);
  230.              if (index < (size >> 1)) {// 如果index<size的一半
  231.                    next = header.next;// 找到index所指的元素
  232.                    for (nextIndex=0; nextIndex<index; nextIndex++)
  233.                       next = next.next;
  234.              } else {
  235.                    next = header;// 从后面遍历,找到所要的元素
  236.                    for (nextIndex=size; nextIndex>index; nextIndex--)
  237.                       next = next.previous;
  238.              }
  239.         }
  240.         
  241.         public boolean hasNext() {// 判断有没有下个元素
  242.              return nextIndex != size;
  243.         }
  244.         
  245.         public E next() {获得下一个元素
  246.              checkForComodification();
  247.              if (nextIndex == size)
  248.                  throw new NoSuchElementException();
  249.              lastReturned = next;
  250.              next = next.next;
  251.              nextIndex++;
  252.              return lastReturned.element;
  253.         }
  254.         
  255.         public boolean hasPrevious() {
  256.              return nextIndex != 0;
  257.         }
  258.         
  259.         public E previous() {
  260.              if (nextIndex == 0)
  261.                  throw new NoSuchElementException();
  262.              lastReturned = next = next.previous;
  263.              nextIndex--;
  264.              checkForComodification();
  265.              return lastReturned.element;
  266.         }
  267.         
  268.         public int nextIndex() {
  269.              return nextIndex;
  270.         }
  271.         
  272.         public int previousIndex() {
  273.              return nextIndex-1;
  274.         }
  275.         
  276.         public void remove() {
  277.                 checkForComodification();
  278.                 Entry<E> lastNext = lastReturned.next;
  279.                 try {
  280.                     LinkedList.this.remove(lastReturned);
  281.                 } catch (NoSuchElementException e) {
  282.                     throw new IllegalStateException();
  283.                 }
  284.                 if (next==lastReturned)
  285.                         next = lastNext;
  286.                     else
  287.                 nextIndex--;
  288.                 lastReturned = header;
  289.                 expectedModCount++;
  290.         }
  291.         
  292.         public void set(E e) {
  293.              if (lastReturned == header)
  294.                  throw new IllegalStateException();
  295.              checkForComodification();
  296.              lastReturned.element = e;
  297.         }
  298.         
  299.         public void add(E e) {
  300.              checkForComodification();
  301.              lastReturned = header;
  302.              addBefore(e, next);
  303.              nextIndex++;
  304.              expectedModCount++;
  305.         }
  306.         
  307.         final void checkForComodification() {//
  308.              if (modCount != expectedModCount)
  309.                  throw new ConcurrentModificationException();
  310.         }
  311.    }
  312.         //上面的这个类是定义在LinkedList中的私有类。他实现了ListIterator具体的分析参照上面的注释。
  313.         public Iterator<E> descendingIterator() {
  314.              return new DescendingIterator();
  315.         }
  316.         private class DescendingIterator implements Iterator {
  317.                 final ListItr itr = new ListItr(size());
  318.                 public boolean hasNext() {
  319.                      return itr.hasPrevious();
  320.                 }
  321.                 public E next() {
  322.                      return itr.previous();
  323.                 }
  324.                 public void remove() {
  325.                     itr.remove();
  326.                 }
  327.         }
  328.         //上面的函数和类仍然返回不同的遍历器。不再解释。
  329.         //不过DescendingIterator 是递减的遍历器。可以注意到他的next()、hasNext()方法的不同。
  330.         public Object clone() {
  331.                 LinkedList<E> clone = null;
  332.                 try {
  333.                      clone = (LinkedList<E>) super.clone();// 先调用父类的克隆函数
  334.                 } catch (CloneNotSupportedException e) {
  335.                      throw new InternalError();
  336.                 }
  337.                 // Put clone into "virgin" state
  338.                 clone.header = new Entry<E>(nullnullnull);// 自己开始复制,先复制头节点
  339.                 clone.header.next = clone.header.previous = clone.header;// 给头结点赋值
  340.                 clone.size = 0;
  341.                 clone.modCount = 0;
  342.                 // Initialize clone with our elements
  343.                 for (Entry<E> e = header.next; e != header; e = e.next)// 把元素也复制过去
  344.                     clone.add(e.element);
  345.                 return clone;
  346.          }
  347.         
  348.         public Object[] toArray() {
  349.                 Object[] result = new Object[size];
  350.                 int i = 0;
  351.                 for (Entry<E> e = header.next; e != header; e = e.next)
  352.                     result[i++] = e.element;
  353.                 return result;
  354.         }
  355.         // 转化成数组。
  356.         public <T> T[] toArray(T[] a) {
  357.                 
  358.                 // 如果a太小了,那么就在重新给a分配空间吧。
  359.                 if (a.length < size)
  360.                     a = (T[])java.lang.reflect.Array.newInstance(
  361.                                         a.getClass().getComponentType(), size);// 如何分配,那么就用反射机制吧。
  362.                 
  363.                 // 有地方放了,好吧数据放入数组中,呵呵。
  364.                 int i = 0;
  365.                 Object[] result = a;
  366.                 for (Entry<E> e = header.next; e != header; e = e.next)
  367.                     result[i++] = e.element;
  368.                 if (a.length > size)  // 如果a长了,a【size】=null,使不能访问后面的元素。
  369.                     a[size] = null;
  370.                 return a;
  371.             }
  372.         private static final long serialVersionUID = 876323262645176354L;
  373.            private void writeObject(java.io.ObjectOutputStream s)
  374.                 throws java.io.IOException {
  375.                // Write out any hidden serialization magic
  376.                s.defaultWriteObject();
  377.                 // Write out size
  378.                 s.writeInt(size);
  379.                 // Write out all elements in the proper order.
  380.                 for (Entry e = header.next; e != header; e = e.next)
  381.                     s.writeObject(e.element);
  382.             }
  383.            
  384.         private void readObject(java.io.ObjectInputStream s)
  385.                 throws java.io.IOException, ClassNotFoundException {
  386.                 // Read in any hidden serialization magic
  387.                 s.defaultReadObject();
  388.                 // Read in size
  389.                 int size = s.readInt();
  390.                 // Initialize header
  391.                 header = new Entry<E>(nullnullnull);
  392.                 header.next = header.previous = header;
  393.                 // Read in all elements in the proper order.
  394.                 for (int i=0; i<size; i++)
  395.                     addBefore((E)s.readObject(), header);
  396.             }
  397.         }
  398.         // 不再说明,很容易理解。就是先写入size,再写入每一个数据,读出也一样,先读取size,再读取对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值