ListIterator和Iterator 源码分析

706 阅读3分钟

总结不同点

我们在使用List,Set的时候,为了实现对其数据的遍历,我们经常使用到了Iterator(迭代器)。使用迭代器,你不需要干涉其遍历的过程,只需要每次取出一个你想要的数据进行处理就可以了。

但是在使用的时候也是有不同的。List和Set都有iterator()来取得其迭代器。对List来说,你也可以通过listIterator()取得其迭代器,两种迭代器在有些时候是不能通用的,Iterator和ListIterator主要区别在以下方面:

  1. ListIterator有add()方法,可以向List中添加对象,而Iterator不能

  2. ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。

  3. ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。

  4. 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。

因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。其实,数组对象也可以用迭代器来实现。 ListIterator 其实就是 对 Iterator 功能的扩展

linkedlist--->类图

图片.png

ListIterator 结构

图片.png

Iterator 结构

图片.png

AbstractList 集合中的Itr 和ListItr 实现类源码

Iterator 接口的实现类Itr

private class Itr implements Iterator<E> {
        /**元素的下标
         * Index of element to be returned by subsequent call to next.
         */
        int cursor = 0;

        /**上一个元素的下标。如果元素已被删除就设置为-1
         * Index of element returned by most recent call to next or
         * previous.  Reset to -1 if this element is deleted by a call
         * to remove.
         */
        int lastRet = -1;

        /**允许修改的次数,违规操作会抛异常
         * The modCount value that the iterator believes that the backing
         * List should have.  If this expectation is violated, the iterator
         * has detected concurrent modification.
         */
        int expectedModCount = modCount;
       /*检查是否还有下一个元素*/
        public boolean hasNext() {
            return cursor != size();
        }
      /*光标下移,并且返回当前的元素*/
        public E next() {
            checkForComodification();
            try {
                int i = cursor;
                E next = get(i);
                lastRet = i;
                cursor = i + 1;
                return next;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }
       /*移除元素*/
        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                AbstractList.this.remove(lastRet);
                if (lastRet < cursor)
                    cursor--;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException e) {
                throw new ConcurrentModificationException();
            }
        }

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

ListIterator接口的实现类ListItr 继承了Itr 类 然后扩展了自己的方法

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

LinkedList 集合使用迭代器源码分析 使用的是LinkedList 集合中自己封装的方法

LinkedList 集合迭代器源码
public ListIterator<E> listIterator(int index) 
{
    checkPositionIndex(index);
    //  构造方法的时候是0
    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) 
    {
        //创建对象的时候初始化 2个属性
        // 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();
    }
}

linkedlist 倒序遍历 源码分析

private class DescendingIterator implements Iterator<E>
{
   // 元素的个数
    private final ListItr itr = new ListItr(size());
    public boolean hasNext() 
    {
        // 其实就是调用的ListItr 类的方法
        return itr.hasPrevious();
    }
    public E next() 
    {
        return itr.previous();
    }
    public void remove() 
    {
        itr.remove();
    }
}

linkedList Demo

 LinkedList<String> list  = new LinkedList();
  list.add("1");
  list.add("2");
  list.add("3");
  Iterator<String> it = list.iterator();
  while (it.hasNext())
  {
      String str = it.next();
      if (str.equals("111"))
      {
          it.remove();
      }
      else
      {
          System.out.println(str);
      }

  }
  // 其实都是一样的  list.iterator 和 list.listIterator 调用的实现方法都是一样
Iterator<String> itr = list.listIterator();
while (itr.hasNext())
{
    System.out.println(itr.next());
    itr.remove();
}

Iterator list2 = list.descendingIterator();
while (list2.hasNext())
{
    System.out.println(list2.next());
    list2.remove();
}