Java数据结构-LinkedList(四)

参考博客:http://www.cnblogs.com/skywang12345/p/3561803.html,表示感谢!

LinkedList 是List接口的一个基于双向链表的实现类,继承了AbstractSequentialList类,实现了List接口,Queue接口(队列),Deque(双端队列),Cloneable接口,Serializable接口。因此LinkedList具有队列的特点,可以作为堆栈,队列,双端队列使用。

和ArrayList一样,LinkedList也是非同步的,如果不需要使用队列的特性的话,一般使用ArrayList。

遍历LinkedList时,使用removeFist()或removeLast()效率最高。但用它们遍历时,

会删除原始数据;若单纯只读取,而不删除,应该使用增强for循环或者iterator的方式,

千万不要使用角标访问的形式来遍历。

LinkedList与Collection关系如下图:



LinkedList的本质是一个双向链表,那么什么是双向链表呢?

双向链表(双链表)是链表的一种。双链表由一个个节点组成,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。

双链表的示意图如下:

表头为空,表头的后继节点为"节点10"(数据为10的节点);"节点10"的后继节点是"节点20"(数据为10的节点),"节点20"的前继节点是"节点10";"节点20"的后继节点是"节点30","节点30"的前继节点是"节点20";...;末尾节点的后继节点是表头。


双链表删除节点

双链表添加节点

LinkedList源码分析:

package java.util;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;

/**
 * @since 1.2
 */
public class LinkedList
   
   
    
     extends AbstractSequentialList
    
    
     
      implements
        List
     
     
      
      , Deque
      
      
       
       , Queue
       
       
         , Cloneable, Serializable { private static final long serialVersionUID = 876323262645176354L; //LinkedList中的元素的数量 transient int size = 0; //双链表中的head,它是空的,不保存数据 transient Link 
        
          voidLink; //LinkedList中的节点,用来保存数据, //每个节点包含向前 向后的节点的引用以及本节点的数据 private static final class Link 
         
           { ET data; Link 
          
            previous, next; Link(ET o, Link 
           
             p, Link 
            
              n) { data = o; previous = p; next = n; } } //LinkedList内部的iterator实现,可以用来进行遍历以及数据的增删修改 private static final class LinkIterator 
             
               implements ListIterator 
              
                { int pos, expectedModCount; final LinkedList 
               
                 list; //当前节点 最后节点的引用 Link 
                
                  link, lastLink; //从指定位置返回LinkedList的iterator LinkIterator(LinkedList 
                 
                   object, int location) { list = object; expectedModCount = list.modCount; //检查角标是否越界 if (location >= 0 && location <= list.size) { // pos ends up as -1 if list is empty, it ranges from -1 to // list.size - 1 // if link == voidLink then pos must == -1 //获取LinkedList的head节点 link = list.voidLink; //根据指定位置判断其位于LinkedList前半部分还是后半部分, //然后决定是从开始查找,还是从后开始查找, //找到指定位置的节点。 //这种根据位置来决定从前半部分还是后半部分查找的方法在LinkedList中很常见也很有效 if (location < list.size / 2) { for (pos = -1; pos + 1 < location; pos++) { link = link.next; } } else { for (pos = list.size; pos >= location; pos--) { link = link.previous; } } } else { throw new IndexOutOfBoundsException(); } } //通过iterator添加元素 public void add(ET object) { if (expectedModCount == list.modCount) { Link 
                  
                    next = link.next;//获取当前节点的下一个节点 //为需要添加的新元素创建一个新的节点对象 //新节点的前一个节点指向当前节点 //新节点的后一个节点指向当前节点的原来的后一节点 //即将新的节点插入原节点于其后一节点之间 Link 
                   
                     newLink = new Link 
                    
                      (object, link, next); link.next = newLink;//将当前节点的下一个节点指向新建的节点 next.previous = newLink;//将原节点的后一节点的向前的引用指向新的节点 link = newLink;//将原节点的引用指向新添加的节点 lastLink = null;//将原来最后一个节点的引用释放,因为位置发生改变 pos++; //指针位置移动 expectedModCount++;//预期修改次数加一 list.size++; //LinkedList元素数量加一 list.modCount++; //LinkedList修改次数加一 } else { throw new ConcurrentModificationException(); } } //返回当前指针位置后面是否还有元素 //如果该节点后面是head节点,则其为LinkedList最后一个节点 //否则后面还有其他元素 public boolean hasNext() { return link.next != list.voidLink; } //返回当前指针位置前面是否还有元素 //如果当前节点不是head节点那么其前面还有元素 public boolean hasPrevious() { return link != list.voidLink; } //获取当前指针位置后面的节点中的元素 public ET next() { if (expectedModCount == list.modCount) {//fail-fase判断 LinkedList.Link 
                     
                       next = link.next;//获取当前阶段的下一节点 if (next != list.voidLink) {//判断是否已经到末尾 lastLink = link = next;//更新引用,向前移动 pos++; //指针位置向前移动 return link.data; //返回数据 } throw new NoSuchElementException(); } throw new ConcurrentModificationException(); } //返回下一角标,即指针位置加一 //指针开始位置为-1,角标开始为0 public int nextIndex() { return pos + 1; } //返回当前指针位置的前一个元素 public ET previous() { if (expectedModCount == list.modCount) { if (link != list.voidLink) { lastLink = link; link = link.previous; pos--; return lastLink.data; } throw new NoSuchElementException(); } throw new ConcurrentModificationException(); } //返回当前指针位置的前一角标,即指针本身位置 //因为指针总是在角标的前一位 public int previousIndex() { return pos; } //移除LinkedList的一个元素 public void remove() { if (expectedModCount == list.modCount) { if (lastLink != null) { Link 
                      
                        next = lastLink.next; Link 
                       
                         previous = lastLink.previous;//获取lastLink前后节点引用 next.previous = previous; previous.next = next;//将lastLink前后节点连接起来 if (lastLink == link) { pos--; //如果移除的是最后一个节点,指针位置减一 } link = previous; lastLink = null; expectedModCount++; list.size--; list.modCount++; } else { throw new IllegalStateException(); } } else { throw new ConcurrentModificationException(); } } //修改lastLink节点的值 public void set(ET object) { if (expectedModCount == list.modCount) { if (lastLink != null) { lastLink.data = object; } else { throw new IllegalStateException(); } } else { throw new ConcurrentModificationException(); } } } //倒序的iterator private class ReverseLinkIterator 
                        
                          implements Iterator 
                         
                           { private int expectedModCount; private final LinkedList 
                          
                            list; private Link 
                           
                             link; private boolean canRemove; ReverseLinkIterator(LinkedList 
                            
                              linkedList) { list = linkedList; expectedModCount = list.modCount; link = list.voidLink; canRemove = false; } public boolean hasNext() { return link.previous != list.voidLink; } public ET next() { if (expectedModCount == list.modCount) { if (hasNext()) { link = link.previous; canRemove = true; return link.data; } throw new NoSuchElementException(); } throw new ConcurrentModificationException(); } public void remove() { if (expectedModCount == list.modCount) { if (canRemove) { Link 
                             
                               next = link.previous; Link 
                              
                                previous = link.next; next.next = previous; previous.previous = next; link = previous; list.size--; list.modCount++; expectedModCount++; canRemove = false; return; } throw new IllegalStateException(); } throw new ConcurrentModificationException(); } } //默认的LinkedList构造函数 //创建一个head节点,其前后节点的引用都指向自己 //为空 public LinkedList() { voidLink = new Link 
                               
                                 (null, null, null); voidLink.previous = voidLink; voidLink.next = voidLink; } //使用一个collection创建一个LinkedList //将collection中所有元素添加到LinkedList中 public LinkedList(Collection 
                                 collection) { this(); addAll(collection); } //添加元素到指定位置 @Override public void add(int location, E object) { if (location >= 0 && location <= size) { Link 
                                
                                  link = voidLink; //获取到指定位置的原有节点 if (location < (size / 2)) { for (int i = 0; i <= location; i++) { link = link.next; } } else { for (int i = size; i > location; i--) { link = link.previous; } } //添加新的节点到原位置节点与其前一个节点之间 //取代原节点的位置 Link 
                                 
                                   previous = link.previous; Link 
                                  
                                    newLink = new Link 
                                   
                                     (object, previous, link); previous.next = newLink; link.previous = newLink; size++; modCount++; } else { throw new IndexOutOfBoundsException(); } } //默认添加元素,添加到末尾 @Override public boolean add(E object) { return addLastImpl(object); } private boolean addLastImpl(E object) { Link 
                                    
                                      oldLast = voidLink.previous; Link 
                                     
                                       newLink = new Link 
                                      
                                        (object, oldLast, voidLink); voidLink.previous = newLink; oldLast.next = newLink; size++; modCount++; return true; } //添加一个collection中的所有元素到LinkedList中,从指定位置开始 //添加的元素顺序为原collection中的顺序 @Override public boolean addAll(int location, Collection 
                                        collection) { if (location < 0 || location > size) { throw new IndexOutOfBoundsException(); } int adding = collection.size(); if (adding == 0) { return false; } Collection 
                                        elements = (collection == this) ? new ArrayList 
                                       
                                         (collection) : collection; Link 
                                        
                                          previous = voidLink; if (location < (size / 2)) { for (int i = 0; i < location; i++) { previous = previous.next; } } else { for (int i = size; i >= location; i--) { previous = previous.previous; } } Link 
                                         
                                           next = previous.next; for (E e : elements) { Link 
                                          
                                            newLink = new Link 
                                           
                                             (e, previous, null); previous.next = newLink; previous = newLink; } previous.next = next; next.previous = previous; size += adding; modCount++; return true; } @Override public boolean addAll(Collection 
                                             collection) { int adding = collection.size(); if (adding == 0) { return false; } Collection 
                                             elements = (collection == this) ? new ArrayList 
                                            
                                              (collection) : collection; Link 
                                             
                                               previous = voidLink.previous; for (E e : elements) { Link 
                                              
                                                newLink = new Link 
                                               
                                                 (e, previous, null); previous.next = newLink; previous = newLink; } previous.next = voidLink; voidLink.previous = previous; size += adding; modCount++; return true; } //添加元素到队列的头部 双端链表的方法 public void addFirst(E object) { addFirstImpl(object); } private boolean addFirstImpl(E object) { Link 
                                                
                                                  oldFirst = voidLink.next; Link 
                                                 
                                                   newLink = new Link 
                                                  
                                                    (object, voidLink, oldFirst); voidLink.next = newLink; oldFirst.previous = newLink; size++; modCount++; return true; } //添加元素到列表的末尾 public void addLast(E object) { addLastImpl(object); } //清空列表 //将head的前后引用指向自身 @Override public void clear() { if (size > 0) { size = 0; voidLink.next = voidLink; voidLink.previous = voidLink; modCount++; } } //clone方法 //复制一个LinkedList然后将当前list加入复制的列表汇中 @SuppressWarnings("unchecked") @Override public Object clone() { try { LinkedList 
                                                   
                                                     l = (LinkedList 
                                                    
                                                      ) super.clone(); l.size = 0; l.voidLink = new Link 
                                                     
                                                       (null, null, null); l.voidLink.previous = l.voidLink; l.voidLink.next = l.voidLink; l.addAll(this); return l; } catch (CloneNotSupportedException e) { throw new AssertionError(e); } } //查找列表中是否包含某个元素 //遍历列表 @Override public boolean contains(Object object) { Link 
                                                      
                                                        link = voidLink.next; if (object != null) { while (link != voidLink) { if (object.equals(link.data)) { return true; } link = link.next; } } else { while (link != voidLink) { if (link.data == null) { return true; } link = link.next; } } return false; } //获取指定位置的元素 //熟悉的根据指定的位置来判断从前端还是后端进行遍历 //从中可以看出,根据角标来获取LinkedList的时候,由于每次 //都需要进行遍历,因此效率较低 //严禁通过这种随机访问的形式来进行LinkedList的遍历 @Override public E get(int location) { if (location >= 0 && location < size) { Link 
                                                       
                                                         link = voidLink; if (location < (size / 2)) { for (int i = 0; i <= location; i++) { link = link.next; } } else { for (int i = size; i > location; i--) { link = link.previous; } } return link.data; } throw new IndexOutOfBoundsException(); } //返回队列的首元素 public E getFirst() { return getFirstImpl(); } private E getFirstImpl() { Link 
                                                        
                                                          first = voidLink.next; if (first != voidLink) { return first.data; } throw new NoSuchElementException(); } //返回列队的末元素 public E getLast() { Link 
                                                         
                                                           last = voidLink.previous; if (last != voidLink) { return last.data; } throw new NoSuchElementException(); } //查找指定元素的角标 @Override public int indexOf(Object object) { int pos = 0; Link 
                                                          
                                                            link = voidLink.next; if (object != null) { while (link != voidLink) { if (object.equals(link.data)) { return pos; } link = link.next; pos++; } } else { while (link != voidLink) { if (link.data == null) { return pos; } link = link.next; pos++; } } return -1; } //倒序查找指定元素的角标 @Override public int lastIndexOf(Object object) { int pos = size; Link 
                                                           
                                                             link = voidLink.previous; if (object != null) { while (link != voidLink) { pos--; if (object.equals(link.data)) { return pos; } link = link.previous; } } else { while (link != voidLink) { pos--; if (link.data == null) { return pos; } link = link.previous; } } return -1; } //返回一个List的iterator @Override public ListIterator 
                                                            
                                                              listIterator(int location) { return new LinkIterator 
                                                             
                                                               (this, location); } //移除指定位置的元素 @Override public E remove(int location) { if (location >= 0 && location < size) { Link 
                                                              
                                                                link = voidLink; if (location < (size / 2)) { for (int i = 0; i <= location; i++) { link = link.next; } } else { for (int i = size; i > location; i--) { link = link.previous; } } Link 
                                                               
                                                                 previous = link.previous; Link 
                                                                
                                                                  next = link.next; previous.next = next; next.previous = previous; size--; modCount++; return link.data; } throw new IndexOutOfBoundsException(); } //移除指定元素 @Override public boolean remove(Object object) { return removeFirstOccurrenceImpl(object); } //移除队列的首元素 public E removeFirst() { return removeFirstImpl(); } private E removeFirstImpl() { Link 
                                                                 
                                                                   first = voidLink.next; if (first != voidLink) { Link 
                                                                  
                                                                    next = first.next; voidLink.next = next; next.previous = voidLink; size--; modCount++; return first.data; } throw new NoSuchElementException(); } //移除队列的末元素 public E removeLast() { return removeLastImpl(); } private E removeLastImpl() { Link 
                                                                   
                                                                     last = voidLink.previous; if (last != voidLink) { Link 
                                                                    
                                                                      previous = last.previous; voidLink.previous = previous; previous.next = voidLink; size--; modCount++; return last.data; } throw new NoSuchElementException(); } //返回一个倒序的iterator public Iterator 
                                                                     
                                                                       descendingIterator() { return new ReverseLinkIterator 
                                                                      
                                                                        (this); } //Deque接口的方法实现 添加元素到队列首位 public boolean offerFirst(E e) { return addFirstImpl(e); } //Deque接口的方法实现,添加元素到队列末位 public boolean offerLast(E e) { return addLastImpl(e); } //Deque接口的方法实现,获取队列首位的元素 //队列为空则返回null public E peekFirst() { return peekFirstImpl(); } //Deque接口方法,获取队列末位元素 //队列为空则返回null public E peekLast() { Link 
                                                                       
                                                                         last = voidLink.previous; return (last == voidLink) ? null : last.data; } //Deque接口方法 //移除队列首位元素并返回 //队列为空则返回null public E pollFirst() { return (size == 0) ? null : removeFirstImpl(); } //Deque方法 //移除队列末位元素并返回 public E pollLast() { return (size == 0) ? null : removeLastImpl(); } //Deque方法 //移除队列首位元素并返回 //与pollFirst方法区别在于队列为空时会抛出异常 public E pop() { return removeFirstImpl(); } //Deque方法 //添加元素到队列首位 public void push(E e) { addFirstImpl(e); } //Deque方法 public boolean removeFirstOccurrence(Object o) { return removeFirstOccurrenceImpl(o); } public boolean removeLastOccurrence(Object o) { Iterator 
                                                                        
                                                                          iter = new ReverseLinkIterator 
                                                                         
                                                                           (this); return removeOneOccurrence(o, iter); } private boolean removeFirstOccurrenceImpl(Object o) { Iterator 
                                                                          
                                                                            iter = new LinkIterator 
                                                                           
                                                                             (this, 0); return removeOneOccurrence(o, iter); } private boolean removeOneOccurrence(Object o, Iterator 
                                                                            
                                                                              iter) { while (iter.hasNext()) { E element = iter.next(); if (o == null ? element == null : o.equals(element)) { iter.remove(); return true; } } return false; } //修改指定位置的元素 @Override public E set(int location, E object) { if (location >= 0 && location < size) { Link 
                                                                             
                                                                               link = voidLink; if (location < (size / 2)) { for (int i = 0; i <= location; i++) { link = link.next; } } else { for (int i = size; i > location; i--) { link = link.previous; } } E result = link.data; link.data = object; return result; } throw new IndexOutOfBoundsException(); } //返回当前列表的元素数量 @Override public int size() { return size; } //添加元素到队列末位 public boolean offer(E o) { return addLastImpl(o); } //移除并返回队列首位元素 public E poll() { return size == 0 ? null : removeFirst(); } //移除并返回队列首位元素 //为空时会抛出异常 public E remove() { return removeFirstImpl(); } //返回队列首位元素 //不会删除元素 //为空时会返回null public E peek() { return peekFirstImpl(); } private E peekFirstImpl() { Link 
                                                                              
                                                                                first = voidLink.next; return first == voidLink ? null : first.data; } //获取首位元素 public E element() { return getFirstImpl(); } //返回列表的数组形式 @Override public Object[] toArray() { int index = 0; Object[] contents = new Object[size]; Link 
                                                                               
                                                                                 link = voidLink.next; while (link != voidLink) { contents[index++] = link.data; link = link.next; } return contents; } //返回列表的数组形式 //如果参数传递的数组够大则使用参数数组 //否则创建新数组 @Override @SuppressWarnings("unchecked") public 
                                                                                
                                                                                  T[] toArray(T[] contents) { int index = 0; if (size > contents.length) { Class 
                                                                                  ct = contents.getClass().getComponentType(); contents = (T[]) Array.newInstance(ct, size); } Link 
                                                                                 
                                                                                   link = voidLink.next; while (link != voidLink) { contents[index++] = (T) link.data; link = link.next; } if (index < contents.length) { contents[index] = null; } return contents; } //序列化方法 //先写入容量即size //再写入每个节点 private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); stream.writeInt(size); Iterator 
                                                                                  
                                                                                    it = iterator(); while (it.hasNext()) { stream.writeObject(it.next()); } } //反序列化方法 //先读取容量即size //再创建LinkedList,读取每个节点加入队列 @SuppressWarnings("unchecked") private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); size = stream.readInt(); voidLink = new Link 
                                                                                   
                                                                                     (null, null, null); Link 
                                                                                    
                                                                                      link = voidLink; for (int i = size; --i >= 0;) { Link 
                                                                                     
                                                                                       nextLink = new Link 
                                                                                      
                                                                                        ((E) stream.readObject(), link, null); link.next = nextLink; link = nextLink; } link.next = voidLink; voidLink.previous = link; } } 
                                                                                       
                                                                                      
                                                                                     
                                                                                    
                                                                                   
                                                                                  
                                                                                 
                                                                                
                                                                               
                                                                              
                                                                             
                                                                            
                                                                           
                                                                          
                                                                         
                                                                        
                                                                       
                                                                      
                                                                     
                                                                    
                                                                   
                                                                  
                                                                 
                                                                
                                                               
                                                              
                                                             
                                                            
                                                           
                                                          
                                                         
                                                        
                                                       
                                                      
                                                     
                                                    
                                                   
                                                  
                                                 
                                                
                                               
                                              
                                             
                                            
                                           
                                          
                                         
                                        
                                       
                                      
                                     
                                    
                                   
                                  
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值