Iterators

Iterable

  • It basically promises that the collection can be iterated
public interface Iterable<T> {
    Iterator<T> iterator();
    void forEach(Consumer<? super T> action);
    Spliterator<T> spliterator();
}
  • All Collections are Iterable
public interface Collection<E> extends Iterable<E> {
    // ...
}

Iterator

  • methods
    • hasNext(): boolean
    • next(): E
    • remove(): void

ListIterator

  • Same as Iterator but provides bidirectional iteration capabilities
  • It is used in List Collections only
  • methods
    • hasNext(), next()
    • hasPrevious(), previous()
    • remove(): void
    • add(E): void
      • Insert new element
    • set(E): void
      • Replaces last element with the given element

Spliterator

  • Splittable Iterator
  • It is same as Iterator but it can split and parallelize the iteration
  • They are used internally in terminal operators in streams:
    • streams are lazily evaluated
    • terminal operators causes the start of iteration and execution

How for-each works

List<String> someList = new ArrayList<>();
someList.add("Apple");
someList.add("Banana");
 
for (String item : someList) {
    // ...
}
 
// same as
for (Iterator<String> i = someList.iterator(); i.hasNext();) {
    String item = i.next();
    // ...
}
  • Array
String[] someArray = new String[2]
someArray[0] = "Apple";
someArray[1] = "Banana";
 
for(String item : someArray) {
    // ...
}
 
// same as
for (int i = 0; i < someArray.length; i++) {
    String item = someArray[i];
    // ...
}

Fail-fast vs Fail-safe

  • Also See Iterator
  • https://www.baeldung.com/java-fail-safe-vs-fail-fast-iterator
  • Fail Fast
    • These throw ConcurrentModificationException if the collection is modified during iteration
    • Collections maintain internal counter modCount to track modifications, which is compared with initial value, if mismatch happens exception is thrown
    • During iteration if iterator.remove() is called, then it is safe
    • If you remove using Collection method like list.remove(2) then it throws exception
    • Examples: Iterators for Collections like ArrayList, HashMap etc.
iterator = numbers.iterator();
while (iterator.hasNext()) {
    if (iterator.next() == 40) {
        iterator.remove(); // safe
        numbers.remove(2); // exception
    }
}
  • Fail Safe
    • These iterators make a copy of collection and then iterate
    • It is not guaranteed to return updated collection after iteration
    • Examples: Iterators for Concurrent Collections like ConcurrentHashMap, CopyOnWriteArrayList etc.

Java Cursor

  • It is used to iterate, traverse, or retrieve a Collection or Stream object’s elements one by one.
  • Types:
    • Enumeration
    • Iterator
    • ListIterator
  • Enumeration
    • Legacy class
  • Iterator
    • Provides forward moving sequential iteration
  • ListIterator
    • extends Iterator
    • Provides Bidirectional iteration capabilities