Java external vs internal iterator
last modified January 27, 2024
Java external vs internal iterator shows the difference between external and internal iterator in Java.
Iterator is an object that enables a programmer to traverse containers such as lists and maps.
Iterator types
There are two types of iterators: external and internal. An external iterator is active, an internal is passive.
When the client (i.e. the programmer) controls the iteration, the iterator is called external iterator. When the iterator controls it, it is called an internal iterator.
Generally, it is recommended to use internal iterator over external iterator. Internal iteration is less error prone, more readable, and requires less code. On the other hand, external iterator is sometimes more flexible; for instance, when doing an operation for two collections in a loop.
Java External Iterator examples
The following examples show the usage of external iterators.
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()); } } }
In the example, we use an external iterator to go through the list of words and print its elements and their size in characters.
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
When we use an external iteration with enhanced-for loop and modify the elements
of a collection, we may receive the ConcurrentModificationException
.
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); } }
In the example, we want to remove all words that equal to "sky" from
a list. This is for demonstrational purposes; since Java 8 we can easily
remove elements with removeIf
method:
words.removeIf(e -> "sky".equals(e));
Exception in thread "main" java.util.ConcurrentModificationException
Running the example leads to ConcurrentModificationException
.
Other forms of external iteration in Java work.
Iterator<String> iter = words.iterator(); while (iter.hasNext()) { String s = iter.next(); if ("sky".equals(s)) { iter.remove(); } }
The example works OK with the old-school iteration with while
loop.
for (int i=words.size() - 1; i>=0; i--) { if ("sky".equals(words.get(i))) { words.remove(i); } }
It also works with the traditional for loop.
Also note that using for each loop in such a case does not lead to error in all languages. For instance, Python 3 or Perl 6 work OK. On the other hand, JavaScript and C++ end up in errors, too.
#!/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))
This is an equivalent code in Python 3. It works OK.
Java Internal Iterator example
In the following examples, we use internal iterators.
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())); } }
The example goes over all elements of a list and prints them and their size.
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); } }
Using modern functional Java, we show how to create a new immutable list that does not contain the "sky" word.
[hello, there, den]
Source
Java Iterator - language reference
In this article we have talked about external and internal iterator in Java.
Author
List all Java tutorials.