Java 中iterator和iterable的关系是怎样的?有何意义?

正在学习集合框架,总是把这两个接口搞混,也没有弄清楚其中的关系,希望得到解答,谢谢
关注者
17
被浏览
10,110
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

首先, Iterator 才是那个可以对集合进行迭代的迭代器。 但不同集合的底层结构不同, 迭代的实现原理也就不同。

例如 ArrayList 是数组结构, LinkedList 是双向链表。他们就不能使用同一种迭代器。

但针对 ArrayList 的迭代器和针对 LinkedList 的迭代器有个共同点, 就是他们都需要一些方法: 例如 hasNext() 和 next(), 我们就可以把这些方法定义在同一个接口 Iterator 里, 再分别给 ArrayList 和 LindedList 找一个实现类来作为各自的迭代器, 分别覆写 hasNext() 和 next() 。

jdk 中给 ArrayList 找的实现类叫作 Itr, 他实现了 Iterator 接口, 针对 ArrayList 的结构覆写了 hasNext() 和 next(), 这个类除了迭代 ArrayList 之外没有其他作用, 所以 jdk 中把 Itr 写成了一个 ArrayList 私有的内部类。

既然私有, 就需要提供一个对外可以获取实例的方法, 这个方法叫作 iterator()。同样的, LinkedList, TreeSet, HashSet 等其他集合也需要通过这种方法获取迭代器实例, 我们就把这个方法定义在 Iterable 接口中, 让以上集合直接或间接实现 Iterable 接口, 覆写 iterator() 方法。


以下是 jdk 源码 (以 ArrayList 为例)


Iterator 接口中的 hasNext() 和 next()

public interface Iterator<E> {

    boolean hasNext();

    E next();

    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}


ArrayList 内部类 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();
        }
    }


Iterable 接口中的 iterator()

public interface Iterable<T> {

    Iterator<T> iterator();

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}


ArrayList 间接实现 Iterable 接口, 覆写 iterator()

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


以上一些浅见