天道不一定酬所有勤
但是,天道只酬勤
Hollis出品的全套Java面试宝典不来了解一下吗?

设计模式(十四)——JDK中的迭代器模式

Hollis出品的全套Java面试宝典不来了解一下吗?

新专题:设计模式,我会在博客(http://www.hollischuang.com)及微信公众号(hollischuang)同步更新,欢迎共同学习。

上一篇介绍了迭代器模式,而且我们也提到,迭代器模式在JAVA的很多集合类中应用广泛,本文就来看看JAVA源码中是如何使用迭代器模式的。

以下这段代码是JAVA中比较常见的,使用迭代器来遍历List:

List<String> list = new ArrayList<>();
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

在上一篇文章中,我们介绍过迭代器模式中包括的几个角色:

Iterator 抽象迭代器

ConcreteIterator 具体迭代器

Aggregate 抽象容器

Concrete Aggregate 具体容器

我们看看ArrayList在使用迭代器的时候是否也包含这些角色。

首先,具体的容器就不用说了,ArrayList类本身就是这个具体的容器类。我们看得到,ArrayList中包含一个iterator方法,该方法用来返回一个具体的迭代器。

在介绍这个具体的迭代器的实现之前,我们先来找找这个迭代器模式的实现中是否包含抽象迭代器和抽象容器。

抽象容器比较好找,只要我们找到这个iterator方法在哪个接口中定义的就可以了。这里直接给出答案:java.util.Iterable

抽象迭代器就是java.util.Iterator

当我们在使用JAVA开发的时候,想使用迭代器模式的话,只要让我们自己定义的容器类实现java.util.Iterable并实现其中的iterator方法使其返回一个java.util.Iterator的实现类就可以了。

我们接下来看一下ArrayList中的iterator方法是如何实现的,直接贴源码(jdk1.8.0_73):

public Iterator<E> iterator() {
    return new Itr();
}

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    public boolean hasNext() {
        return cursor != size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
        checkForComodification();
        int i = cursor;
        if (i >= size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }

    public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public void forEachRemaining(Consumer<? super E> consumer) {
        Objects.requireNonNull(consumer);
        final int size = ArrayList.this.size;
        int i = cursor;
        if (i >= size) {
            return;
        }
        final Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length) {
            throw new ConcurrentModificationException();
        }
        while (i != size && modCount == expectedModCount) {
            consumer.accept((E) elementData[i++]);
        }
        // update once at end of iteration to reduce heap write traffic
        cursor = i;
        lastRet = i - 1;
        checkForComodification();
    }

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

上面的代码比较简单,应该都可以看得懂,这里的实现很容易理解,就是iterator方法中new了一个Iterator的实现类并反回了。Itr是一个内部类,他实现了Iterator接口并实现了其中的方法。

至此,看完了JAVA中ArrayList对迭代器模式的实现。通过迭代器,可以不必关心其内部实现方式。

当我们在使用JAVA开发的时候,想使用迭代器模式的话,只要让我们自己定义的容器类实现java.util.Iterable并实现其中的iterator方法使其返回一个java.util.Iterator的实现类就可以了。

赞(3)
如未加特殊说明,此网站文章均为原创,转载必须注明出处。HollisChuang's Blog » 设计模式(十四)——JDK中的迭代器模式
Hollis出品的全套Java面试宝典不来了解一下吗?

评论 抢沙发

HollisChuang's Blog

联系我关于我