What is Java Iterator?
An Iterator in Java is an object that provides a way to access elements of a collection sequentially without exposing the underlying collection’s structure. It belongs to the java.util package and is part of the Java Collections Framework. The primary purpose of an Iterator is to traverse elements in a collection, making it an essential tool for developers working with lists, sets, or other collections.
Why Use an Iterator in Java?
Iterators are particularly useful when:
- You want to traverse a collection element by element.
- You need to perform operations like removing elements during iteration.
- The collection’s implementation details should remain hidden from the traversal logic.
Features of Java Iterator
- Traverses Elements: Allows sequential traversal of elements in a collection.
- Removes Elements: Provides the ability to remove elements during iteration using the remove() method.
- Unified Approach: Works uniformly across various collection types (e.g., ArrayList, HashSet).
Iterator Interface in Java
The Iterator interface defines three key methods:
hasNext():
Returns true
if there are more elements to iterate over.
Syntax:
boolean hasNext();
next():
Returns the next element in the iteration.
Syntax:
E next();
remove():
Removes the last element returned by the next() method.
Syntax:
void remove();
How to Use an Iterator in Java
To use an Iterator, follow these steps:
- Obtain an Iterator from the collection using the iterator() method.
- Use hasNext() to check if more elements are available.
- Use next() to retrieve the next element.
- Optionally, use remove() to delete the current element.
Example: Iterating Through an ArrayList
import java.util.*;
public class IteratorExample {
public static void main(String[] args) {
// Create an ArrayList
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
// Get the Iterator
Iterator<String> iterator = fruits.iterator();
// Traverse the collection
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
}
}
}
Output:
Apple
Banana
Cherry
Example: Removing Elements During Iteration
import java.util.*;
public class RemoveExample {
public static void main(String[] args) {
// Create a list of numbers
List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
// Get the Iterator
Iterator<Integer> iterator = numbers.iterator();
// Remove even numbers
while (iterator.hasNext()) {
int num = iterator.next();
if (num % 2 == 0) {
iterator.remove();
}
}
// Print the updated list
System.out.println("Updated List: " + numbers);
}
}
Output:
Updated List: [1, 3, 5]
Important Points to Remember
- Fail-Fast Behavior:
Iterators are fail-fast, meaning they throw a ConcurrentModificationException if the collection is modified during iteration by anything other than the Iterator’s remove() method. - Single-Use:
An Iterator can only traverse a collection once. If you need to traverse it again, create a new Iterator. - Type Safety:
In generic collections, the Iterator enforces type safety. For example:
List<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator();
Iterator vs Enhanced for Loop
- Iterator:
- Provides more control (e.g., ability to remove elements during iteration).
- Suitable for situations where fine-grained control over the collection is required.
- Enhanced for Loop:
- Simplifies traversal but lacks the ability to modify the collection during iteration.
- Example:
for (String fruit : fruits) {
System.out.println(fruit);
}
Iterator vs ListIterator
- Iterator:
- Works with all collection types.
- Allows forward traversal only.
- Cannot add elements during iteration.
- ListIterator:
- Works only with lists (ArrayList, LinkedList).
- Supports forward and backward traversal.
- Allows adding, modifying and removing elements during iteration.
Example: ListIterator
import java.util.*;
public class ListIteratorExample {
public static void main(String[] args) {
List<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob", "Charlie"));
// Get the ListIterator
ListIterator<String> listIterator = names.listIterator();
// Traverse forward
while (listIterator.hasNext()) {
System.out.println("Forward: " + listIterator.next());
}
// Traverse backward
while (listIterator.hasPrevious()) {
System.out.println("Backward: " + listIterator.previous());
}
}
}
Output:
Forward: Alice
Forward: Bob
Forward: Charlie
Backward: Charlie
Backward: Bob
Backward: Alice
Advantages of Using Iterator
- Provides a standard way to traverse collections.
- Removes elements safely during iteration.
- Prevents accidental modification of the collection.
Common Use Cases for Iterator
- Removing elements based on a condition.
- Iterating over a collection where the type is unknown at compile time.
- Traversing custom collections.