Iterator and Iterable
An object that moves through a collection
Iterator<E> represents sequential traversal of elements.
It keeps the current position and answers two main questions:
is there another element, and which element should be returned next?
List<String> names = List.of("Ann", "Bob", "Cara");
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
System.out.println(name);
}
hasNext() checks whether any elements remain,
and next() returns the next one and advances the iterator.
Calling next() after the end of the sequence causes an exception.
Iterable makes an object traversable
The Iterable<T> interface requires an iterator() method.
That is what allows an object to be used in a for-each loop.
Most collections implement Iterable through their hierarchy.
for (String name : names) {
System.out.println(name);
}
This loop is shorter than working with an iterator manually, but the idea underneath is the same: obtain a traversal object and request elements one by one.
Safe removal during traversal
Ordinary modification of the collection from somewhere else while iterating can disrupt the traversal.
If you need to remove the current element, the iterator-supported approach is to use its
remove() after next().
List<String> values = new ArrayList<>(List.of("keep", "remove", "keep"));
Iterator<String> it = values.iterator();
while (it.hasNext()) {
if (it.next().equals("remove")) {
it.remove();
}
}