多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# Java 外部与内部迭代器 原文:http://zetcode.com/java/externalinternaliterator/ Java 外部和内部迭代器展示了 Java 中外部和内部迭代器之间的区别。 迭代器是使程序员能够遍历列表和映射之类的容器的对象。 ## 迭代器类型 迭代器有两种类型:外部和内部。 外部迭代器是主动的,内部迭代器是被动的。 当客户端(即程序员)控制迭代时,该迭代器称为外部迭代器。 当迭代器控制它时,它称为内部迭代器。 通常,建议使用内部迭代器而不是外部迭代器。 内部迭代不易出错,更易读,并且需要更少的代码。 另一方面,外部迭代器有时更灵活。 例如,在循环中对两个集合进行操作时。 ## Java 外部迭代器示例 以下示例显示了外部迭代器的用法。 `JavaExternalIterationEx.java` ```java package com.zetcode; import java.util.List; public class JavaExternalIterationEx { public static void main(String[] args) { List<String> words = List.of("hello", "sky", "there", "den", "sky"); for (String word: words) { System.out.printf("The word %s has %d characters%n", word, word.length()); } } } ``` 在示例中,我们使用外部迭代器遍历单词列表,并以字符形式显示其元素及其大小。 ```java The word hello has 5 characters The word sky has 3 characters The word there has 5 characters The word den has 3 characters The word sky has 3 characters ``` 这是输出。 ### `ConcurrentModificationException` 当我们使用带有增强型`for`循环的外部迭代并修改集合的元素时,我们可能会收到`ConcurrentModificationException`。 `JavaExternalIterationEx2.java` ```java package com.zetcode; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class JavaExternalIterationEx2 { public static void main(String[] args) { List<String> words = new ArrayList<>(Arrays.asList("pen", "pencil", "sky", "blue", "sky", "dog")); for (String word: words) { if ("sky".equals(word)) { words.remove(word); } } System.out.println(words); } } ``` 在该示例中,我们要从列表中删除所有等于`"sky"`的单词。 这是出于演示目的; 从 Java8 开始,我们可以轻松地使用`removeIf()`方法删除元素:`words.removeIf(e -> "sky".equals(e));` ```java Exception in thread "main" java.util.ConcurrentModificationException ``` 运行示例将导致`ConcurrentModificationException`。 Java 工作中其他形式的外部迭代。 ```java Iterator<String> iter = words.iterator(); while (iter.hasNext()) { String s = iter.next(); if ("sky".equals(s)) { iter.remove(); } } ``` 该示例可以在带有`while`循环的老式迭代中正常运行。 ```java for (int i=words.size() - 1; i>=0; i--) { if ("sky".equals(words.get(i))) { words.remove(i); } } ``` 它也可以与传统的`for`循环一起使用。 还要注意,在这种情况下,为每个循环使用并不会导致所有语言的错误。 例如,Python 3 或 Perl 6 可以正常工作。 另一方面,JavaScript 和 C++ 也会出错。 `extit.py` ```java #!/usr/bin/python3 words = ["pen", "pencil", "dog", "sky", "blue", "sky"] print(len(words)) for word in words: if word == "sky": words.remove(word) print(words) print(len(words)) ``` 这是 Python 3 中的等效代码。可以正常工作。 ## Java 内部迭代器示例 在以下示例中,我们使用内部迭代器。 `JavaInternalIteratorEx.java` ```java package com.zetcode; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class JavaInternalIteratorEx { public static void main(String[] args) { List<String> words = List.of("hello", "sky", "there", "den", "sky"); words.stream().forEach(e -> System.out.printf("The word %s has %d characters %n", e, e.length())); } } ``` 该示例遍历列表的所有元素,并打印它们及其大小。 `JavaInternalIteratorEx2.java` ```java package com.zetcode; import java.util.List; import java.util.stream.Collectors; public class JavaInternalIteratorEx2 { public static void main(String[] args) { List<String> words = List.of("hello", "sky", "there", "den", "sky"); List<String> words2 = words.stream().filter(e -> !"sky".equals(e)) .collect(Collectors.toList()); System.out.println(words2); } } ``` 使用现代函数式 Java,我们展示了如何创建一个不包含`"sky"`一词的新不可变列表。 ```java [hello, there, den] ``` 这是输出。 在本教程中,我们讨论了 Java 的内部和外部迭代器。 您可能也对相关教程感兴趣: [Java 复制文件](/java/copyfile/), [Java 创建目录](/java/createdirectory/), [Java 文件大小](/java/filesize/),[用 Java 创建文件](/java/createfile/) ,[用 Java 读取文本文件](/articles/javareadtext/), [Apache FileUtils 教程](/java/fileutils/), [Java Swing 教程](/tutorials/javaswingtutorial/)和 [Java 教程](/lang/java/)。