Java > Java Collections Framework > Iterators and Streams > Using Iterator and ListIterator
Using Iterator and ListIterator in Java
This demonstrates how to use Iterator and ListIterator to traverse and manipulate elements within Java Collections. Understanding iterators and list iterators are fundamental for efficient collection handling.
Iterator Example: Traversing a List
This example illustrates basic iteration using the Iterator.  We create an ArrayList of strings, obtain an Iterator from it using names.iterator(), and then loop through the list using the hasNext() and next() methods. The hasNext() method checks if there are more elements, and next() retrieves the next element.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorExample {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        Iterator<String> iterator = names.iterator();
        while (iterator.hasNext()) {
            String name = iterator.next();
            System.out.println(name);
        }
    }
}ListIterator Example: Traversing and Modifying a List
This example demonstrates the ListIterator. Unlike the regular Iterator, ListIterator allows bidirectional traversal and modification of the list.  The code first traverses the list forward, replacing "Bob" with "Robert". Then, it traverses the list backward using hasPrevious() and previous(). Finally, it prints the modified list.
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.List;
public class ListIteratorExample {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        ListIterator<String> listIterator = names.listIterator();
        // Forward traversal and modification
        while (listIterator.hasNext()) {
            String name = listIterator.next();
            if (name.equals("Bob")) {
                listIterator.set("Robert"); // Replace Bob with Robert
            }
        }
        // Backward traversal
        System.out.println("\nBackward Traversal:");
        while (listIterator.hasPrevious()) {
            String name = listIterator.previous();
            System.out.println(name);
        }
        System.out.println("\nModified List: " + names);
    }
}Concepts Behind Iterators and ListIterators
Iterator and ListIterator are interfaces that provide a way to access elements of a collection sequentially. Iterator is a simpler interface that allows forward-only traversal and element removal. ListIterator extends Iterator and offers bidirectional traversal, element modification, and insertion. The key methods are: hasNext(): Checks if there are more elements.next(): Returns the next element.remove(): Removes the last element returned by next() (only in Iterator).hasPrevious(): Checks if there are elements before the current position (only in ListIterator).previous(): Returns the previous element (only in ListIterator).set(E e): Replaces the last element returned by next() or previous() with the specified element (only in ListIterator).add(E e): Inserts the specified element into the list (only in ListIterator).
Real-Life Use Case
Imagine you have a list of transactions, and you need to process them one by one.  Using an Iterator or ListIterator allows you to access each transaction, perform some operation (e.g., update a database), and potentially remove or modify the transaction based on the processing result.  For example, you could use a ListIterator to update a sales order line item to reflect a discount, and iterate backwards if validation fails.
Best Practices
Iterator (except by calling the remove() method of the Iterator itself). This can lead to ConcurrentModificationException. Use ListIterator for modification if possible.Iterator is sufficient. If you need to traverse backward or modify elements, use ListIterator.hasNext() or hasPrevious() before calling next() or previous() to prevent NoSuchElementException.
Interview Tip
Be prepared to explain the differences between Iterator and ListIterator.  Focus on bidirectional traversal and modification capabilities of ListIterator. Also, understand the implications of modifying a collection directly during iteration and the use of ConcurrentModificationException.
When to Use Them
Iterator when you need to traverse a collection and potentially remove elements.ListIterator when you need to traverse a list in both directions, modify elements, or insert new elements.  It is the only means for modifying a List while iterating it.
Memory Footprint
Iterators generally have a small memory footprint. They don't load the entire collection into memory at once but access elements sequentially. The memory footprint primarily depends on the underlying collection being iterated.
Alternatives
Pros
ListIterator) during iteration.
Cons
Iterator and ListIterator interfaces.ConcurrentModificationException.
FAQ
- 
                        What is aConcurrentModificationException?
 AConcurrentModificationExceptionis thrown when a collection is structurally modified while an iterator is being used to traverse it, and the modification is not done through the iterator's ownremove()oradd()methods (in case ofListIterator).
- 
                        When should I useListIteratorinstead ofIterator?
 UseListIteratorwhen you need to traverse a list in both directions, modify elements, or insert new elements during iteration. If you only need to traverse forward and remove elements,Iteratoris sufficient.
- 
                        Can I use anIteratorwith any type of Collection?
 Yes, you can use anIteratorwith any class that implements theCollectioninterface. Each collection class provides its own implementation of theiterator()method, which returns anIteratorsuitable for that collection type.
