Iterator迭代器

2018-04-27  本文已影响0人  kindol

Iterator<E>接口

Iterator<E>接口含有3个方法

public interface Iterator<E>{
    E next();
    boolean hasNext();
    void remove();
}

ListIterator接口

相比于Iterator,还包括add,previous,hasPrevious方法,LinkedList类就实现了此接口

previous,hasPrevious和next,hasNext同,只是一个顺着一个逆着遍历,当然,在调用remove的时候,删除的是越过的元素,而并不是说一定为迭代器左边的元素

java中的链表都是双向链表,所以会有previous,hasPrevious,add方法仅针对资源有序的集合,也就是说,add方法将会添加到当前的iterator后面,如果iterator刚创建,也就是在头结点前,此时调用add则此新节点将会变成头结点

对于set等无序集合,在iterator接口是实现add方法就没有意义,所以Collection拓展的是Iterator接口,没有包括add方法

Collection

Collection接口拓展了Iterator接口,也就是说所有的

foreach

foreach循环可以和任何实现了Iterable接口的对象一起工作,这个接口只有一个方法

public interface Iterable<E>{
    Iterator<E> iterator();
}

AbstractList中Iterator的实现

在iterator接口中返回了一个内部类Itr

private class Itr implements Iterator<E> {
    //下一个元素的索引位置
    int cursor = 0;

    //上一个元素的索引位置,这个值将会变成-1在调用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();
    }
}

next()的实现是通过get(cursor)然后cursor++,通过这样实现遍历

而在remove()中,有这么一句“expectedModCount = modCount”,这是一种称为“快速失败”的机制,提供了迭代过程中集合的安全性,也就是说迭代过程中不允许修改集合

modCount记录修改此列表的次数:包括改变列表的结构,改变列表的大小,打乱列表的顺序等使正在进行迭代产生错误的结果。

每次增删操作都有modCount++,通过和expectedModCount的对比,迭代器可以快速的知道迭代过程中是否存在list.add()类似的操作,存在的话快速失败!

然而,需要注意的是,仅仅设置元素的值并不是结构的修改

上一篇 下一篇

猜你喜欢

热点阅读