LinkedList

1. 切记一定不要使用普通for循环去遍历LinkedList。使用迭代器或者foreach循环

原因:for循环时获取每个节点的时候都调用到了LinkedList的get()方法,从以下代码的20行~29行可以看出每一次获得一个节点的值都是从头开始for下去,当LinkedList里面的元素越来越多,则花费的时间就成倍增加,LinikedList遍历的时间复杂度为O(N  2  ) 

 

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 
13  
14  /** 
15       * Returns the (non-null) Node at the specified element index.
    16       */ 
17         Node<E> node( int index) {
    18          // assert isElementIndex(index); 
19  
20          if (index < ( size >> 1 )) {
    21                 Node<E> x = first;
    22              for ( int i = 0; i < index; i++ )
    23                     x = x.next;
    24              return x;
    25             } else {
   26               Node<E> x = last;
    27              for ( int i = size - 1; i > index; i-- )
    28                     x = x.prev;
    29              return x;
    30          }
    31         }

 

 

而使用迭代器或者foreach循环内部实现的代码是

 private  class ListItr extends Itr implements ListIterator<E> { 
        ListItr( int index) { 
            cursor = index; 
        }

        public  boolean hasPrevious() {
                return cursor != 0 ; 
        }

        public E previous() { 
            checkForComodification(); 
            try {
                    int i = cursor - 1 ; 
                E previous = get(i); 
                lastRet = cursor = i;
                    return previous; 
            } catch (IndexOutOfBoundsException e) { 
                checkForComodification(); 
                throw  new NoSuchElementException (); 
            } 
        }

        public  int nextIndex() {
                return cursor; 
        }

        public  int previousIndex() {
                return cursor-1 ; 
        }

        public  void set(E e) {
                if (lastRet < 0 )
                    throw  new IllegalStateException(); 
            checkForComodification();

            try { 
                AbstractList. this .set(lastRet, e); 
                expectedModCount = modCount; 
            } catch (IndexOutOfBoundsException ex) {
                    throw  new ConcurrentModificationException(); 
            } 
        }

        public  void add(E e) { 
            checkForComodification();

            try {
                    int i = cursor; 
                AbstractList. this .add(i, e); 
                lastRet = -1 ; 
                cursor = i + 1 ; 
                expectedModCount = modCount; 
            } catch (IndexOutOfBoundsException ex) {
                    throw  new ConcurrentModificationException(); 
            } 
        } 
    }

从代码中可以看出,迭代器相当有一个游标cursor,可以直接获取后一个或者前一个的值,它遍历的时间复杂度O(N

 

posted @ 2017-11-13 17:47  七月蜀葵  阅读(126)  评论(0编辑  收藏  举报