Java迭代器Iterator和Iterable有什么区别?

52 阅读2分钟
  • IterableIterable 是一个接口,代表一个集合可以使用增强型 for 循环 (for-each) 进行迭代。它定义了一个 iterator() 方法,返回一个 Iterator,从而为集合提供遍历功能。任何实现了 Iterable 接口的类,都可以通过 for-each 循环来遍历其元素。

  • IteratorIterator 是一个用于遍历集合元素的对象。它提供了 hasNext()next() 方法,用于按顺序访问集合中的每个元素,并且还可以通过 remove() 方法删除当前遍历到的元素。

一个集合如果 extends Iterable< E >
则代表这个集合有可以迭代的功能,而且一个集合如果继承自Iterable,那么他必须要实现

Iterator<T> iterator();

public interface Iterable<T> {
    Iterator<T> iterator();

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        Iterator var2 = this.iterator();

        while(var2.hasNext()) {
            T t = var2.next();
            action.accept(t);
        }

    }

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

这个方法,Iterator是一个用于遍历集合元素的对象

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package java.util;

import java.util.function.Consumer;

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(this.hasNext()) {
            action.accept(this.next());
        }

    }
}

DK 1.8 时,Iterable 接口中新增了 forEach 方法。该方法接受一个 Consumer 对象作为参数,用于对集合中的每个元素执行指定的操作。该方法的实现方式是使用 for-each 循环遍历集合中的元素,对于每个元素,调用 Consumer 对象的 accept 方法执行指定的操作。

    List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
    list.forEach(integer -> System.out.println(integer));

写的简单一点就是:

List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
list.forEach(new Consumer<Integer>() {
    @Override
    public void accept(Integer integer) {
        System.out.println(integer);
    }
});

只要一个 List 实现了 Iterable 接口,它就可以使用 for-each 进行遍历,因为 for-each 循环背后依赖于 Iterable 接口提供的 iterator() 方法来获取 Iterator,从而完成遍历。
Map 就没办法直接使用 for-each,因为 Map 没有实现 Iterable 接口,只有通过 map.entrySet()map.keySet()map.values() 这种返回一个 Collection 的方式才能 使用 for-each。