原文:http://zetcode.com/java/externalinternaliterator/

Java 外部和内部迭代器展示了 Java 中外部和内部迭代器之间的区别。

迭代器是使程序员能够遍历列表和映射之类的容器的对象。

迭代器类型

迭代器有两种类型:外部和内部。 外部迭代器是主动的,内部迭代器是被动的。

当客户端(即程序员)控制迭代时,该迭代器称为外部迭代器。 当迭代器控制它时,它称为内部迭代器。

通常,建议使用内部迭代器而不是外部迭代器。 内部迭代不易出错,更易读,并且需要更少的代码。 另一方面,外部迭代器有时更灵活。 例如,在循环中对两个集合进行操作时。

Java 外部迭代器示例

以下示例显示了外部迭代器的用法。

JavaExternalIterationEx.java

  1. package com.zetcode;
  2. import java.util.List;
  3. public class JavaExternalIterationEx {
  4. public static void main(String[] args) {
  5. List<String> words = List.of("hello", "sky", "there", "den", "sky");
  6. for (String word: words) {
  7. System.out.printf("The word %s has %d characters%n",
  8. word, word.length());
  9. }
  10. }
  11. }

在示例中,我们使用外部迭代器遍历单词列表,并以字符形式显示其元素及其大小。

  1. The word hello has 5 characters
  2. The word sky has 3 characters
  3. The word there has 5 characters
  4. The word den has 3 characters
  5. The word sky has 3 characters

这是输出。

ConcurrentModificationException

当我们使用带有增强型for循环的外部迭代并修改集合的元素时,我们可能会收到ConcurrentModificationException

JavaExternalIterationEx2.java

  1. package com.zetcode;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.List;
  5. public class JavaExternalIterationEx2 {
  6. public static void main(String[] args) {
  7. List<String> words = new ArrayList<>(Arrays.asList("pen", "pencil",
  8. "sky", "blue", "sky", "dog"));
  9. for (String word: words) {
  10. if ("sky".equals(word)) {
  11. words.remove(word);
  12. }
  13. }
  14. System.out.println(words);
  15. }
  16. }

在该示例中,我们要从列表中删除所有等于"sky"的单词。 这是出于演示目的; 从 Java8 开始,我们可以轻松地使用removeIf()方法删除元素:words.removeIf(e -> "sky".equals(e));

  1. Exception in thread "main" java.util.ConcurrentModificationException

运行示例将导致ConcurrentModificationException

Java 工作中其他形式的外部迭代。

  1. Iterator<String> iter = words.iterator();
  2. while (iter.hasNext()) {
  3. String s = iter.next();
  4. if ("sky".equals(s)) {
  5. iter.remove();
  6. }
  7. }

该示例可以在带有while循环的老式迭代中正常运行。

  1. for (int i=words.size() - 1; i>=0; i--) {
  2. if ("sky".equals(words.get(i))) {
  3. words.remove(i);
  4. }
  5. }

它也可以与传统的for循环一起使用。

还要注意,在这种情况下,为每个循环使用并不会导致所有语言的错误。 例如,Python 3 或 Perl 6 可以正常工作。 另一方面,JavaScript 和 C++ 也会出错。

extit.py

  1. #!/usr/bin/python3
  2. words = ["pen", "pencil", "dog", "sky", "blue", "sky"]
  3. print(len(words))
  4. for word in words:
  5. if word == "sky":
  6. words.remove(word)
  7. print(words)
  8. print(len(words))

这是 Python 3 中的等效代码。可以正常工作。

Java 内部迭代器示例

在以下示例中,我们使用内部迭代器。

JavaInternalIteratorEx.java

  1. package com.zetcode;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.List;
  5. public class JavaInternalIteratorEx {
  6. public static void main(String[] args) {
  7. List<String> words = List.of("hello", "sky", "there", "den", "sky");
  8. words.stream().forEach(e ->
  9. System.out.printf("The word %s has %d characters %n", e, e.length()));
  10. }
  11. }

该示例遍历列表的所有元素,并打印它们及其大小。

JavaInternalIteratorEx2.java

  1. package com.zetcode;
  2. import java.util.List;
  3. import java.util.stream.Collectors;
  4. public class JavaInternalIteratorEx2 {
  5. public static void main(String[] args) {
  6. List<String> words = List.of("hello", "sky", "there", "den", "sky");
  7. List<String> words2 = words.stream().filter(e -> !"sky".equals(e))
  8. .collect(Collectors.toList());
  9. System.out.println(words2);
  10. }
  11. }

使用现代函数式 Java,我们展示了如何创建一个不包含"sky"一词的新不可变列表。

  1. [hello, there, den]

这是输出。

在本教程中,我们讨论了 Java 的内部和外部迭代器。 您可能也对相关教程感兴趣: Java 复制文件Java 创建目录Java 文件大小用 Java 创建文件用 Java 读取文本文件Apache FileUtils 教程Java Swing 教程Java 教程