Java 8 Internal Iterators vs External Iterators
This article explains external and internal iterators with examples, compares them and then shows how internal iterators are meant to be used with Java 8 Streams API.
External Iterators Definition(or Active Iterators)
With external iterators responsibility of iterating over the elements, and making sure that this iteration takes into account the total number of records, whether more records exist to be iterated and so on lies with the programmer.
A brief look at the evolution of external iterators in java
Lets look into some external iterators which we have been using as java language evolved over the years.
Starting with Enumerations, iterations then moved on to
However, though we are explicitly not invoking
All the above ways - Enumerations, Iterators and enhanced for-loop seem the natural way of iterating right!! Well yes, but then managing the iterations still remains the programmer's job. Well not anymore with the advent of Internal Iterators in Java 8. Internal Iterators(or Passive Iterators) Internal Iterators manage the iterations in the background. This leaves the programmer to just declaratively code what is meant to be done with the elements of the Collection, rather than managing the iteration and making sure that all the elements are processed one-by-one.
Lets see how simple it is to say print all elements in an
In the above code, we are just telling the
All the work of iterating over the list of names one by one and printing them is taken care of internally by the runtime, leaving us with just declaratively defining only what is to be done i.e. print the names. Advantage of internal iterators over external iterators
The
Starting with Enumerations, iterations then moved on to
Iterators
(remember iterator()
, next()
or hasNext()
methods for iterators). Then came Java 5 and along with came the enhanced for-loop which made use of generics to make iteration a lot easier. Lets see an example of enhanced for-loop introduced in Java 5 which uses the Iterable
interface (you might already be familiar with this one) - Enhanced for-loop example (uses external iterator)
import java.util.*;
public class ExternalIterator {
public static void main(String args[]){
List<String> namesList=Arrays.asList("Tom", "Dick", "Harry");
for(String name:namesList){
System.out.println(name);
}
}
}
hasNext()
or next()
methods while iterating over the list above, still the underlying code which makes this iteration work uses these methods. This implies that the complexity behind these operations is hidden from the programmer but it still exists. And it still is an active iterator.All the above ways - Enumerations, Iterators and enhanced for-loop seem the natural way of iterating right!! Well yes, but then managing the iterations still remains the programmer's job. Well not anymore with the advent of Internal Iterators in Java 8. Internal Iterators(or Passive Iterators) Internal Iterators manage the iterations in the background. This leaves the programmer to just declaratively code what is meant to be done with the elements of the Collection, rather than managing the iteration and making sure that all the elements are processed one-by-one.
Lets see how simple it is to say print all elements in an
ArrayList
in Java 8 using an example of internal iterator based forEach
loop - Example of internal iteration based forEach loop in Java 8
import java.util.*;
public class InternalIterator {
public static void main(String args[]){
List<String> namesList=Arrays.asList("Tom", "Dick", "Harry");
namesList.forEach(name -> System.out.println(name));//Internal Iteration
}
}
forEach
method what to do(i.e. print) with each String in the namesList
list using a lambda expression( In case you are not familiar with lambda expressions you can read the tutorial hereLink to Lambda Expressions Tutorial).All the work of iterating over the list of names one by one and printing them is taken care of internally by the runtime, leaving us with just declaratively defining only what is to be done i.e. print the names. Advantage of internal iterators over external iterators
- Improved code readability as its declarative in nature
- Concise code as multiple lines of code for external iterators is reduced to just one or two lines of code in case of internal iterators
- Simplified implementation/less defects as code written by programmer is very less, chances of bugs creeping into the iteration logic are not there.
forEach
method, we could have made use of the java 8 Streams API to first create a Stream
of elements in the List and then pipeline the stream into a forEach
method like this - Java 8 way to create a stream and then iterate internally
namesList.stream().forEach(name -> System.out.println(name));//Internal Iteration
forEach
method comes under the category of terminal operationsClick to Read Tutorial explaining intermediate & terminal Stream operations when working with streams i.e. it ends the chain of pipelined operations to produce a result.
Note - You can also use internal iterators with parallelStream()
method instead of a stream to improve on the performance.
Summary
We looked at the external iterators being used uptil Java 7, then understood what are internal iterators with Java 8's forEach
method, then saw few advantages of internal iterators over external ones, and finally saw how forEach
works when used with java 8 Streams API.