Detailed source of java LinkedList

Detailed source of java LinkedList

Class definition

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    //链表元素(节点)的个数
    transient int size = 0;

    /**
     *指向第一个节点的指针
     */
    transient Node<E> first;

    /**
     *指向最后一个节点的指针
     */
    transient Node<E> last;

    public LinkedList() {
    }

    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

     private void linkFirst(E e) {
         final Node<E> f = first;//将头节点赋值给 f
         final Node<E> newNode = new Node<>(null, e, f);//将指定元素构造成一个新节点,此节点的指向下一个节点的引用为头节点
         first = newNode;//将新节点设为头节点,那么原先的头节点 f 变为第二个节点
         if (f == null)//如果第二个节点为空,也就是原先链表是空
             last = newNode;//将这个新节点也设为尾节点(前面已经设为头节点了)
         else
             f.prev = newNode;//将原先的头节点的上一个节点指向新节点
         size++;//节点数加1
         modCount++;//和ArrayList中一样,iterator和listIterator方法返回的迭代器和列表迭代器实现使用。
     }

     void linkLast(E e) {
         final Node<E> l = last;//将l设为尾节点
         final Node<E> newNode = new Node<>(l, e, null);//构造一个新节点,节点上一个节点引用指向尾节点l
         last = newNode;//将尾节点设为创建的新节点
         if (l == null)//如果尾节点为空,表示原先链表为空
             first = newNode;//将头节点设为新创建的节点(尾节点也是新创建的节点)
         else
             l.next = newNode;//将原来尾节点下一个节点的引用指向新节点
         size++;//节点数加1
         modCount++;//和ArrayList中一样,iterator和listIterator方法返回的迭代器和列表迭代器实现使用。
     }

    void linkBefore(E e, Node<E> succ) {
        final Node<E> pred = succ.prev;//将pred设为插入节点的上一个节点
        final Node<E> newNode = new Node<>(pred, e, succ);//将新节点的上引用设为pred,下引用设为succ
        succ.prev = newNode;//succ的上一个节点的引用设为新节点
        if (pred == null)//如果插入节点的上一个节点引用为空
            first = newNode;//新节点就是头节点
        else
            pred.next = newNode;//插入节点的下一个节点引用设为新节点
        size++;
        modCount++;
    }

     private E unlinkFirst(Node<E> f) {
         // assert f == first && f != null;
         final E element = f.item;
         final Node<E> next = f.next;//next 为头结点的下一个节点
         f.item = null;
         f.next = null; // 将节点的元素以及引用都设为 null,便于垃圾回收
         first = next; //修改头结点为第二个节点
         if (next == null)//如果第二个节点为空(当前链表只存在第一个元素)
             last = null;//那么尾节点也置为 null
         else
             next.prev = null;//如果第二个节点不为空,那么将第二个节点的上一个引用置为 null
         size--;
         modCount++;
         return element;
     }

     private E unlinkLast(Node<E> l) {
         // assert l == last && l != null;
         final E element = l.item;
         final Node<E> prev = l.prev;
         l.item = null;
         l.prev = null; //将节点的元素以及引用都设为 null,便于垃圾回收
         last = prev;//尾节点为倒数第二个节点
         if (prev == null)//如果倒数第二个节点为null
             first = null;//那么将节点也置为 null
         else
             prev.next = null;//如果倒数第二个节点不为空,那么将倒数第二个节点的下一个引用置为 null
         size--;
         modCount++;
         return element;
     }

     E unlink(Node<E> x) {
         // assert x != null;
         final E element = x.item;
         final Node<E> next = x.next;
         final Node<E> prev = x.prev;
 
         if (prev == null) {//如果删除节点位置的上一个节点引用为null(表示删除第一个元素)
             first = next;//将头结点置为第一个元素的下一个节点
         } else {//如果删除节点位置的上一个节点引用不为null
             prev.next = next;//将删除节点的上一个节点的下一个节点引用指向删除节点的下一个节点(去掉删除节点)
             x.prev = null;//删除节点的上一个节点引用置为null
         }
 
         if (next == null) {//如果删除节点的下一个节点引用为null(表示删除最后一个节点)
             last = prev;//将尾节点置为删除节点的上一个节点
         } else {//不是删除尾节点
            next.prev = prev;//将删除节点的下一个节点的上一个节点的引用指向删除节点的上一个节点
             x.next = null;//将删除节点的下一个节点引用置为null
         }
 
         x.item = null;//删除节点内容置为null,便于垃圾回收
         size--;
         modCount++;
         return element;
     }

    public E getFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }

    public E getLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;
    }

      //从此列表中移除并返回第一个元素
      public E removeFirst() {
         final Node<E> f = first;//f设为头结点
         if (f == null)
             throw new NoSuchElementException();//如果头结点为空,则抛出异常
         return unlinkFirst(f);
     }

      //从该列表中删除并返回最后一个元素
      public E removeLast() {
          final Node<E> l = last;
          if (l == null)//如果尾节点为空,表示当前集合为空,抛出异常
              throw new NoSuchElementException();
          return unlinkLast(l);
      }

      //将指定的元素附加到链表头节点
      public void addFirst(E e) {
          linkFirst(e);
      }

      //将元素添加到链表末尾
      public void addLast(E e) {
          linkLast(e);
      }

    public boolean contains(Object o) {
        return indexOf(o) != -1;
    }

    public int size() {
        return size;
    }

      //将元素添加到链表末尾
      public boolean add(E e) {
          linkLast(e);
          return true;
      }

    public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

      //按照指定集合的​​迭代器返回的顺序,将指定集合中的所有元素追加到此列表的末尾。
      public boolean addAll(Collection<? extends E> c) {
          return addAll(size, c);
      }
      //将集合 c 中所有元素插入到指定索引的位置。
      public boolean addAll(int index, Collection<? extends E> c) {
          //判断索引 index >= 0 && index <= size中时抛出IndexOutOfBoundsException异常
          checkPositionIndex(index);
 
         Object[] a = c.toArray();//将集合转换成一个 Object 类型的数组
         int numNew = a.length;
         if (numNew == 0)//如果添加的集合为空,直接返回false
             return false;
 
         Node<E> pred, succ;
         if (index == size) {//如果插入的位置等于链表的长度,就是将原集合元素附加到链表的末尾
             succ = null;
             pred = last;
         } else {
             succ = node(index);
             pred = succ.prev;
         }
 
         for (Object o : a) {//遍历要插入的元素
             @SuppressWarnings("unchecked") E e = (E) o;
             Node<E> newNode = new Node<>(pred, e, null);
             if (pred == null)
                 first = newNode;
             else
                 pred.next = newNode;
             pred = newNode;
         }
 
         if (succ == null) {
             last = pred;
         } else {
             pred.next = succ;
             succ.prev = pred;
         }
 
         size += numNew;
         modCount++;
         return true;
     }

    public void clear() {
        // Clearing all of the links between nodes is "unnecessary", but:
        // - helps a generational GC if the discarded nodes inhabit
        //   more than one generation
        // - is sure to free memory even if there is a reachable Iterator
        for (Node<E> x = first; x != null; ) {
            Node<E> next = x.next;
            x.item = null;
            x.next = null;
            x.prev = null;
            x = next;
        }
        first = last = null;
        size = 0;
        modCount++;
    }


    // Positional Access Operations
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }

    public E set(int index, E element) {
        //判断索引 index >= 0 && index <= size中时抛出IndexOutOfBoundsException异常
        checkElementIndex(index);
        Node<E> x = node(index);//获取指定索引处的元素
        E oldVal = x.item;
        x.item = element;//将指定位置的元素替换成要修改的元素
        return oldVal;//返回指定索引位置原来的元素
    }

    //将指定的元素插入此列表中的指定位置
    public void add(int index, E element) {
        //判断索引 index >= 0 && index <= size中时抛出IndexOutOfBoundsException异常
        checkPositionIndex(index);

        if (index == size)//如果索引值等于链表大小
            linkLast(element);//将节点插入到尾节点
        else
            linkBefore(element, node(index));
    }

      //删除此列表中指定位置的元素
      public E remove(int index) {
          //判断索引 index >= 0 && index <= size中时抛出IndexOutOfBoundsException异常
          checkElementIndex(index);
          return unlink(node(index));
      }

    private boolean isElementIndex(int index) {
        return index >= 0 && index < size;
    }

    private boolean isPositionIndex(int index) {
        return index >= 0 && index <= size;
    }

    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }

    private void checkElementIndex(int index) {
        if (!isElementIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private void checkPositionIndex(int index) {
        if (!isPositionIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    Node<E> node(int index) {
        if (index < (size >> 1)) {//如果插入的索引在前半部分
            Node<E> x = first;//设x为头节点
            for (int i = 0; i < index; i++)//从开始节点到插入节点索引之间的所有节点向后移动一位
                x = x.next;
            return x;
        } else {//如果插入节点位置在后半部分
            Node<E> x = last;//将x设为最后一个节点
            for (int i = size - 1; i > index; i--)//从最后节点到插入节点的索引位置之间的所有节点向前移动一位
                x = x.prev;
            return x;
        }
    }

    // Search Operations
     //返回此列表中指定元素第一次出现的索引,如果此列表不包含元素,则返回-1。
     public int indexOf(Object o) {
         int index = 0;
         if (o == null) {//如果查找的元素为null(LinkedList可以允许null值)
             for (Node<E> x = first; x != null; x = x.next) {//从头结点开始不断向下一个节点进行遍历
                 if (x.item == null)
                     return index;
                 index++;
             }
         } else {//如果查找的元素不为null
             for (Node<E> x = first; x != null; x = x.next) {
                 if (o.equals(x.item))
                     return index;
                 index++;
             }
         }
         return -1;//找不到返回-1
     }

    public int lastIndexOf(Object o) {
        int index = size;
        if (o == null) {
            for (Node<E> x = last; x != null; x = x.prev) {
                index--;
                if (x.item == null)
                    return index;
            }
        } else {
            for (Node<E> x = last; x != null; x = x.prev) {
                index--;
                if (o.equals(x.item))
                    return index;
            }
        }
        return -1;
    }

    // Queue operations.
    public E peek() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
    }

    public E element() {
        return getFirst();
    }

    public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }

      //从此列表中移除并返回第一个元素
      public E remove() {
          return removeFirst();
      }

    public boolean offer(E e) {
        return add(e);
    }

    // Deque operations
    public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }

    public boolean offerLast(E e) {
        addLast(e);
        return true;
    }

    public E peekFirst() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
     }

    public E peekLast() {
        final Node<E> l = last;
        return (l == null) ? null : l.item;
    }

    public E pollFirst() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }

    public E pollLast() {
        final Node<E> l = last;
        return (l == null) ? null : unlinkLast(l);
    }

    public void push(E e) {
        addFirst(e);
    }

    public E pop() {
        return removeFirst();
    }

    public boolean removeFirstOccurrence(Object o) {
        return remove(o);
    }

    public boolean removeLastOccurrence(Object o) {
        if (o == null) {
            for (Node<E> x = last; x != null; x = x.prev) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = last; x != null; x = x.prev) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

    public ListIterator<E> listIterator(int index) {
        checkPositionIndex(index);
        return new ListItr(index);
    }

    private class ListItr implements ListIterator<E> {
        private Node<E> lastReturned;
        private Node<E> next;
        private int nextIndex;
        private int expectedModCount = modCount;

        ListItr(int index) {
            // assert isPositionIndex(index);
            next = (index == size) ? null : node(index);
            nextIndex = index;
        }

        public boolean hasNext() {
            return nextIndex < size;
        }

        public E next() {
            checkForComodification();
            if (!hasNext())
                throw new NoSuchElementException();

            lastReturned = next;
            next = next.next;
            nextIndex++;
            return lastReturned.item;
        }

        public boolean hasPrevious() {
            return nextIndex > 0;
        }

        public E previous() {
            checkForComodification();
            if (!hasPrevious())
                throw new NoSuchElementException();

            lastReturned = next = (next == null) ? last : next.prev;
            nextIndex--;
            return lastReturned.item;
        }

        public int nextIndex() {
            return nextIndex;
        }

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

        public void remove() {
            checkForComodification();
            if (lastReturned == null)
                throw new IllegalStateException();

            Node<E> lastNext = lastReturned.next;
            unlink(lastReturned);
            if (next == lastReturned)
                next = lastNext;
            else
                nextIndex--;
            lastReturned = null;
            expectedModCount++;
        }

        public void set(E e) {
            if (lastReturned == null)
                throw new IllegalStateException();
            checkForComodification();
            lastReturned.item = e;
        }

        public void add(E e) {
            checkForComodification();
            lastReturned = null;
            if (next == null)
                linkLast(e);
            else
                linkBefore(e, next);
            nextIndex++;
            expectedModCount++;
        }

        public void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            while (modCount == expectedModCount && nextIndex < size) {
                action.accept(next.item);
                lastReturned = next;
                next = next.next;
                nextIndex++;
            }
            checkForComodification();
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

     private static class Node<E> {
         E item;//实际存储的元素
         Node<E> next;//指向上一个节点的引用
         Node<E> prev;//指向下一个节点的引用
 
         //构造函数
         Node(Node<E> prev, E element, Node<E> next) {
             this.item = element;
             this.next = next;
             this.prev = prev;
         }
     }

    public Iterator<E> descendingIterator() {
        return new DescendingIterator();
    }

    private class DescendingIterator implements Iterator<E> {
        private final ListItr itr = new ListItr(size());
        public boolean hasNext() {
            return itr.hasPrevious();
        }
        public E next() {
            return itr.previous();
        }
        public void remove() {
            itr.remove();
        }
    }

    @SuppressWarnings("unchecked")
    private LinkedList<E> superClone() {
        try {
            return (LinkedList<E>) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e);
        }
    }

    public Object clone() {
        LinkedList<E> clone = superClone();

        // Put clone into "virgin" state
        clone.first = clone.last = null;
        clone.size = 0;
        clone.modCount = 0;

        // Initialize clone with our elements
        for (Node<E> x = first; x != null; x = x.next)
            clone.add(x.item);

        return clone;
    }

    public Object[] toArray() {
        Object[] result = new Object[size];
        int i = 0;
        for (Node<E> x = first; x != null; x = x.next)
            result[i++] = x.item;
        return result;
    }

    @SuppressWarnings("unchecked")
    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 (Node<E> x = first; x != null; x = x.next)
            result[i++] = x.item;

        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 {
        // Write out any hidden serialization magic
        s.defaultWriteObject();

        // Write out size
        s.writeInt(size);

        // Write out all elements in the proper order.
        for (Node<E> x = first; x != null; x = x.next)
            s.writeObject(x.item);
    }

    @SuppressWarnings("unchecked")
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        // Read in any hidden serialization magic
        s.defaultReadObject();

        // Read in size
        int size = s.readInt();

        // Read in all elements in the proper order.
        for (int i = 0; i < size; i++)
            linkLast((E)s.readObject());
    }

    @Override
    public Spliterator<E> spliterator() {
        return new LLSpliterator<E>(this, -1, 0);
    }

    /** A customized variant of Spliterators.IteratorSpliterator */
    static final class LLSpliterator<E> implements Spliterator<E> {
        static final int BATCH_UNIT = 1 << 10;  // batch array size increment
        static final int MAX_BATCH = 1 << 25;  // max batch array size;
        final LinkedList<E> list; // null OK unless traversed
        Node<E> current;      // current node; null until initialized
        int est;              // size estimate; -1 until first needed
        int expectedModCount; // initialized when est set
        int batch;            // batch size for splits

        LLSpliterator(LinkedList<E> list, int est, int expectedModCount) {
            this.list = list;
            this.est = est;
            this.expectedModCount = expectedModCount;
        }

        final int getEst() {
            int s; // force initialization
            final LinkedList<E> lst;
            if ((s = est) < 0) {
                if ((lst = list) == null)
                    s = est = 0;
                else {
                    expectedModCount = lst.modCount;
                    current = lst.first;
                    s = est = lst.size;
                }
            }
            return s;
        }

        public long estimateSize() { return (long) getEst(); }

        public Spliterator<E> trySplit() {
            Node<E> p;
            int s = getEst();
            if (s > 1 && (p = current) != null) {
                int n = batch + BATCH_UNIT;
                if (n > s)
                    n = s;
                if (n > MAX_BATCH)
                    n = MAX_BATCH;
                Object[] a = new Object[n];
                int j = 0;
                do { a[j++] = p.item; } while ((p = p.next) != null && j < n);
                current = p;
                batch = j;
                est = s - j;
                return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);
            }
            return null;
        }

        public void forEachRemaining(Consumer<? super E> action) {
            Node<E> p; int n;
            if (action == null) throw new NullPointerException();
            if ((n = getEst()) > 0 && (p = current) != null) {
                current = null;
                est = 0;
                do {
                    E e = p.item;
                    p = p.next;
                    action.accept(e);
                } while (p != null && --n > 0);
            }
            if (list.modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

        public boolean tryAdvance(Consumer<? super E> action) {
            Node<E> p;
            if (action == null) throw new NullPointerException();
            if (getEst() > 0 && (p = current) != null) {
                --est;
                E e = p.item;
                current = p.next;
                action.accept(e);
                if (list.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                return true;
            }
            return false;
        }

        public int characteristics() {
            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
        }
    }

}

With respect to the collection ArrayList, LinkedList implements a collection of more than  Deque  interface, which is a two-way interface to the queue, the queue is a two-way both sides can be increased and delete operations.

 As shown below:

  

  FIG LinkedList on the four elements, i.e. the Node four objects, size = 4, head points to the first elementA, tail points to the last node elementD.

  LinkedList has two constructors, the first one is empty default constructor, by adding the second set of instances of the Collection of the LinkedList existing element, is called the addAll () method.

  Note: LinkedList list size is not initialized constructor, since lists like array, the array is a defined size must be determined, and then to allocate memory space, but the list is not the same, it does not determine the size, by the pointer moving to the next pointer to the allocated memory address.

 

Adding elements

  ①, addfirst (E)

  Adds the specified element to the head of the list

  ②, addlast (E) 和 add (E e)

  Add the specified element to the end of the list

  ③、add(int index, E element)

  The specified element into the specified position in this list

  ④、addAll(Collection<? extends E> c)

  In the order specified collection returned iterator will set all the elements specified in this list is appended.

  This method also has a addAll (int index, Collection <? Extends E> c), the set of all the elements c inserted into the specified location index. in fact 

  addAll(Collection<? extends E> c) ==  addAll(size, Collection<? extends E> c)

A variety of ways to add elements to the LinkedList collection, we find that every time you add elements LinkedList just change a pointer reference to the element and the next pointer reference, and there is no expansion. , In contrast to the ArrayList, capacity is needed, and in the middle of insertion elements, all the elements have to move back a large difference in efficiency when the two insert elements, this next blog will the efficiency of both, and how choose which set of cases for analysis.

  Also, each time adding operation, has modCount ++ operation,

 

Removing elements

  Delete elements and adding elements, just as by changing the point on one node to the next node and reference point, not as graphic here shows.

  ①、remove()和removeFirst()

  Removed from this list and returns the first element

  ②、removeLast()

  Remove from this list and returns the last element

  ③、remove(int index)

  Delete this list element at the location

  ④、remove(Object o)

  If there is, delete from the list of the first occurrence of the specified element

  On this method is essentially and remove (int index) not much difference, delete judging by circulation elements should be noted, is an element to delete the first occurrence, not all.

 

Modify elements

  By calling set (int index, E element) method, replacing the elements specified position in this list with the specified elements.

  This is mainly acquired by the specified index node (index) method node, this node can then modify the position of the element.

 

Finding Elements

  ①、getFirst()

  Returns the first element in this list

  ②、getLast()

  Returns the last element in this list

  ③、get(int index)

  Returns the element at the specified index

  ④、indexOf(Object o)

  Returns the index in this list of the first occurrence of the specified element, if this list contains no elements or -1.

 

Through the collection

  ①, ordinary for loop

LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("A");
linkedList.add("B");
linkedList.add("C");
linkedList.add("D");
for(int i = 0 ; i < linkedList.size() ; i++){
    System.out.print(linkedList.get(i)+" ");//A B C D
}

  The code is simple, we use the LinkedList get (int index) method, traversing all the elements.

  However, note that, get (int index) method every time before traversing all the elements of the index, so understanding this sentence:

  The above example, a LinkedList set, I into the A, B, C, D is an element. A total of four times to traverse:

  The first time through print A: Just once traversed.

  Second pass print B: you need to find A, B and then find the print.

  Third pass printing C: I need to find A, and then find the B, C and finally found the print.

  Fourth traversal print D: you need to find A, then find B, and then locate C, and finally found D.

  If this collection of elements a lot more to find the back (of course here get method has been optimized to find the first half of traversing from the front, look for the second half of traversing from behind, but the time required is still a lot) more time spent . So how do you improve it?

  ②, iterators

 LinkedList<String> linkedList = new LinkedList<>();
 linkedList.add("A");
 linkedList.add("B");
 linkedList.add("C");
 linkedList.add("D");
 
 
 Iterator<String> listIt = linkedList.listIterator();
 while(listIt.hasNext()){
     System.out.print(listIt.next()+" ");//A B C D
 }
 
 //通过适配器模式实现的接口,作用是倒叙打印链表
 Iterator<String> it = linkedList.descendingIterator();
 while(it.hasNext()){
     System.out.print(it.next()+" ");//D C B A
 }

  In LinkedList collection class also has an internal ListItr, implemented method substantially similar, by moving the cursor point to each of the secondary element traversed without starting from scratch before traversing an element.

  It is important to note here that modCount field, in front of us add and remove elements that they will be increment operator modCount, because if you want to while iteration, delete or add while operating with a set of built-in method will throw abnormal. (Additions and deletions method using an iterator does not throw an exception)

 LinkedList<String> linkedList = new LinkedList<>();
 linkedList.add("A");
 linkedList.add("B");
 linkedList.add("C");
linkedList.add("D");
 
 
 Iterator<String> listIt = linkedList.listIterator();
 while(listIt.hasNext()){
     System.out.print(listIt.next()+" ");//A B C D
     //linkedList.remove();//此处会抛出异常
     listIt.remove();//这样可以进行删除操作
 }

  Another form is to use iterator foreach loop, the underlying implementation is used by iterators

LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("A");
linkedList.add("B");
linkedList.add("C");
linkedList.add("D");
for(String str : linkedList){
    System.out.print(str + "");
}

Iterators and for cycle efficiency differences

  LinkedList<Integer> linkedList = new LinkedList<>();
 for(int i = 0 ; i < 10000 ; i++){//向链表中添加一万个元素
     linkedList.add(i);
}
 long beginTimeFor = System.currentTimeMillis();
 for(int i = 0 ; i < 10000 ; i++){
     System.out.print(linkedList.get(i));
 }
 long endTimeFor = System.currentTimeMillis();
 System.out.println("使用普通for循环遍历10000个元素需要的时间:"+ (endTimeFor - beginTimeFor));
 
 
 long beginTimeIte = System.currentTimeMillis();
 Iterator<Integer> it = linkedList.listIterator();
 while(it.hasNext()){
     System.out.print(it.next()+" ");
 }
 long endTimeIte = System.currentTimeMillis();
 System.out.println("使用迭代器遍历10000个元素需要的时间:"+ (endTimeIte - beginTimeIte));

 Iterator: after each visit of an element, the element will be recorded position of the current visit by the cursor, traversing an element, a record position.

 

 

Published 370 original articles · won praise 88 · views 290 000 +

Guess you like

Origin blog.csdn.net/qq_35029061/article/details/100537471