In Java, there are two major advantages of using iterators.
1. Idiomatic and Safe Traversal
Take this code,
List<Integer> numbers = new ArrayList<>(Arrays.asList(1,2,3,4));
for(int i=0; i<numbers.size(); i++){
System.out.println(numbers.get(i));
if(numbers.get(i) == 2)
numbers.remove(i);
}
The intention of the above code snippet is to iterate through the ArrayList and remove the element 2 when it is encountered.
This loop is doing something sneaky. On the surface it seems like its working correctly but we're actually skipping checking 3 at all. Since the we have removed 2 from the ArrayList as we are iterating through it, the size of numbers has reduced which then causes us to skip the element 3.
Note: This can be fixed without using iterators and instead looping backwards as shown below.
List<Integer> numbers = new ArrayList<>(Arrays.asList(1,2,3,4));
for(int i=numbers.size()-1; i>=0; i--){
System.out.println(numbers.get(i));
if(numbers.get(i) == 2)
numbers.remove(i);
}
But this isnt idiomatic and is hard to read. Its instead better to use iterators as shown below.
List<Integer> numbers = new ArrayList<>(Arrays.asList(1,2,3,4));
Iterator<Integer> it = numbers.iterator();
while(it.hasNext()){
if(it.next() == 2)
it.remove();
}
Now the iterator knows that it deleted an element and loops through the rest of the items correctly.
2. Traverse Forward and Backward
Although true that this cannot be done using a plain iterator, we need to use iterator pro ie, ListIterator.
List<Integer> numbers = new ArrayList<>(Arrays.asList(1,2,3,4));
ListIterator<Integer> it = numbers.listIterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println();
while(it.hasPrevious()){
System.out.println(it.previous());
}