Java 中的 Iterator 与 foreach 对比

2025 年 1 月 7 日 | 阅读 3 分钟

Java 提供了几种遍历集合(如数组、列表、集合和映射)的方法。其中最常用的两种方法是 Iterator 和 foreach。理解这两种方法之间的区别对于编写高效且易于阅读的 Java 代码至关重要。

Iterator

Java 中的 Iterator 接口是 java.util 包的一部分,它提供了一种逐个遍历对象集合的方法。下面我们来仔细看看它是如何工作的。

通过调用集合的 iterator() 方法来创建一个 Iterator。它提供了三个主要方法:

  • hasNext(): 如果迭代还有更多元素,则返回 true。
  • next(): 返回迭代中的下一个元素。
  • remove(): 删除由迭代器最后返回的元素。

文件名:IteratorExample.java

输出

 
Apple
Banana
Cherry   

使用 Iterator 的优点

灵活性: Iterator 接口对迭代过程提供了更多的控制。例如,我们可以使用 remove() 方法在迭代过程中有条件地删除元素。

向后兼容性: 由于 Iterator 自 Java 2 (JDK 1.2) 以来就存在,因此它与旧版本的 Java 兼容。

使用 Iterator 的缺点

冗长: 与 foreach 循环相比,使用 Iterator 的代码往往更冗长。

易出错: 错误地使用 remove() 可能导致 IllegalStateException。

Foreach 循环

Foreach 循环(也称为增强 for 循环)在 Java 5 (JDK 1.5) 中引入,作为遍历数组和集合的更简单方法。

文件名:ForeachExample.java

输出

 
Apple
Banana
Cherry   

使用 Foreach 的优点

简洁性: foreach 循环更简单且更具可读性,减少了样板代码。

安全性: 它不允许在迭代期间修改集合,从而避免了 ConcurrentModificationException。

使用 Foreach 的缺点

控制有限: foreach 循环不支持在迭代期间删除元素或修改集合。

缺少索引访问: 它不提供对当前索引的访问,这在某些情况下可能是有必要的。

性能考虑

Iterator 和 foreach 之间的性能通常相当,但在特定场景下可能会出现细微差异。

Foreach: 在内部,foreach 循环为集合使用 Iterator 接口,因此性能相似。对于数组,由于开销较小,它稍微快一些。

Iterator: 在某些情况下,手动使用 Iterator 可能稍慢,因为需要额外的函数调用 (hasNext(), next()),但这种差异通常可以忽略不计。

何时使用 Iterator

在删除元素时: 如果需要在迭代过程中删除元素,请使用 Iterator,因为 foreach 循环不支持删除。

遗留代码: 在处理需要 Iterator 的遗留代码或库时,最好坚持使用它以保持一致性。

何时使用 Foreach

简单迭代: 对于不需要修改的简单迭代,foreach 因其简洁性和可读性而成为最佳选择。

避免 ConcurrentModificationException: 如果不需要修改集合,foreach 更安全,因为它能防止结构性修改。

结论

Iteratorforeach 在 Java 编程中都有其用武之地。它们之间的选择取决于代码的具体要求。

当您需要对迭代过程进行细粒度控制时,请使用 Iterator,特别是当您需要删除元素或需要处理复杂的迭代逻辑时。

对于简单的迭代,请使用 foreach 来获得更清晰、更易读的代码。此外,foreach 更不易出错且更简洁,是大多数不需要修改集合的常见迭代任务的理想选择。了解何时使用每种方法将帮助我们编写更高效、更易于维护的 Java 代码。