Java Iterable 接口详解

更新于 2025-12-26

Jakob Jenkov 2020-05-25

Java 的 Iterable 接口表示一个可迭代的对象集合——也就是说,该集合中的元素可以被遍历。实现 Iterable 接口的类,其元素就可以通过多种方式进行迭代。

你可以通过以下三种方式遍历一个 Iterable 对象:

  1. 使用 for-each 循环
  2. 通过调用 iterator() 方法获取一个 Java Iterator
  3. 调用 IterableforEach() 方法

本文将依次展示这三种遍历方式的示例。

使用 for-each 循环遍历 Iterable

遍历 Iterable 元素的第一种方式是使用 Java for-each 循环。下面是一个通过 for-each 循环遍历 Java List 的示例:

List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");

for (String element : list) {
    System.out.println(element.toString());
}

此示例首先创建了一个新的 List 并添加了三个元素,然后使用 for-each 循环遍历列表中的每个元素,并打印其 toString() 值。


通过 Iterator 遍历 Iterable

第二种方式是通过调用 Iterableiterator() 方法获取一个 Iterator,然后像操作普通 Iterator 一样进行遍历。更多关于 Iterator 的内容,请参阅我的 Java Iterator 教程

以下是使用 Iterator 遍历 Iterable(本例中为 List)的示例:

List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");

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

使用 forEach() 方法遍历 Iterable

第三种方式是调用 IterableforEach() 方法。该方法接收一个 Java Lambda 表达式 作为参数,该表达式会对 Iterable 中的每个元素执行一次。

示例如下:

List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");

list.forEach((element) -> {
    System.out.println(element);
});

Iterable 接口定义

Java 的 Iterable 接口包含三个方法,其中只有一个必须实现,其余两个提供了默认实现。接口定义如下:

public interface Iterable<T> {
    Iterator<T> iterator();
    Spliterator<T> spliterator();
    void forEach(Consumer<? super T> action);
}

必须实现的方法是 iterator(),它需要返回一个可用于遍历对象元素的 Iterator。当你在 for-each 循环中使用 Iterable 时,编译器会在背后自动调用此方法并生成相应的迭代代码。


Java 中 Iterable 的实现类

Iterable 接口(java.lang.Iterable)是 Java Collections API 的根接口之一,因此 Java 中有许多类实现了该接口,从而支持对其内部元素进行遍历。

此外,还有一些 Java 接口继承自 Iterable。任何实现这些子接口的类,也间接实现了 Iterable 接口。

例如:

  • Collection 接口继承自 Iterable
  • ListSet 接口继承自 Collection,因此也实现了 Iterable

自定义 Iterable 实现

如果你想让自己的类支持 for-each 循环,你需要实现 Iterable 接口。具体实现方法在我的 Java 泛型教程 - 实现 Iterable 接口 中有详细说明。

这里仅给出一个简单的示例:

public class Persons implements Iterable<Person> {
    private List<Person> persons = new ArrayList<Person>();

    public Iterator<Person> iterator() {
        return this.persons.iterator();
    }
}

使用方式如下:

Persons persons = ... // 获取包含 Person 对象的 Persons 实例
for (Person person : persons) {
    // 对 person 对象进行操作
}

获取 Spliterator

你可以通过 Iterablespliterator() 方法获取一个 Spliterator 对象。本文不深入讲解 Spliterator,仅展示如何获取:

List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");

Spliterator<String> spliterator = list.spliterator();

Iterable 的性能考量

如果你的代码需要在紧密循环中反复遍历集合(例如每秒数千次遍历一个 List),那么使用 for-each 循环会比使用传统的 for 循环稍慢:

for (int i = 0; i < list.size(); i++) {
    Object obj = list.get(i);
}

原因在于:每次 for-each 循环都会调用 List.iterator() 方法,从而创建一个新的 Iterator 对象。如果每秒创建成千上万甚至上百万个对象,会产生一定的性能开销。

不过,对于大多数常规业务应用而言,这种性能差异完全可以忽略不计。只有在极高频率的循环场景下才需考虑。