- What is an Iterator in Java?
- It allows:
- Why Use Iterator?
- Problems with Traditional for Loop That Led to Iterator
- 1. Collections Without Indexes
- 2. Code Becomes Complex for Non-Indexed Collections
- 3. Unsafe Removal During Iteration
- 4. No Flexibility in Traversal
- Basic Structure of Iterator
- Explanation:
- Common Methods of Iterator Interface:
- Example 1: Basic Usage with ArrayList
- Explanation
- Example 2: Removing Elements
- Explanation
- Common Mistakes to Avoid
- Using remove() without calling next():
- Modifying the list while using a loop (without iterator):
- Internal Working of Iterator
- Here is a detailed Explanation
- 1. What Happens When You Call iterator()?
- 2. How hasNext() Works
- 3. How next() Works
- 4. How remove() Works
- 🔒 Safety Rule:
- When to Use Iterator?
- Iterator vs ListIterator
- Example 3: Iterator with HashSet
- Output (Order may vary):
- Real-World Analogy
- Iterator Interface Declaration (For Reference)
- Summary
Imagine you have a basket full of fruits 🍎🍌🍇, and you want to look at each fruit one by one. In Java, collections like lists, sets, and maps are like that basket. But how do you go through each element one by one? That’s where the Iterator comes in.
In this tutorial, we’ll cover everything you need to know about Iterator in Java, from basics to advanced usage, with examples that help you visualize and truly understand how it works.
What is an Iterator in Java?
Iterator is an interface in Java’s Collection Framework that provides a universal method to traverse (iterate) through collections like ArrayList, HashSet, LinkedList, etc.
It allows:
- Sequential access to elements of a collection
- Safe element removal during iteration
Iterator is found in the java.util package.
import java.util.Iterator;
Why Use Iterator?
Before Iterator, Java collections could be traversed using for loops or while loops, but they didn’t provide a unified way across different types of collections. Also, removing items during a loop could cause errors.
Iterator solves these problems by:
- Providing a Standard Way to Traverse Any Collection (regardless of index support).
- Safe Element Removal During Iteration using
iterator.remove(). - Works Uniformly Across All Collection Types, like
Set,Queue,List, etc. - Avoids Index Logic—simplifies iteration code, especially for unordered collections.
Problems with Traditional for Loop That Led to Iterator
1. Collections Without Indexes
- Collections like
HashSet,TreeSet, andLinkedHashSetdo not maintain order and do not support index-based access. - The traditional
for (int i = 0; i < ...; i++)loop only works with structures like arrays orArrayListwhere elements are accessed by index.
❌ You can’t do
set.get(i)with aHashSet– it has no index.2. Code Becomes Complex for Non-Indexed Collections
- Without index access, you would have to convert collections to arrays or lists just to iterate, which is inefficient and adds extra code.
❌ Manual conversion just for iteration wastes memory and time.
3. Unsafe Removal During Iteration
- Using a
forloop or enhancedfor-eachloop, if you try to remove an element from the collection during iteration, it throws aConcurrentModificationException.
❌ You cannot safely remove elements using
set.remove()inside afororfor-eachloop.
4. No Flexibility in Traversal
- The
forloop doesn’t give control over how you traverse—no ability to skip, remove, or conditionally break out based on internal behavior easily.
Basic Structure of Iterator
Iterator<Type> iterator = collection.iterator();
while (iterator.hasNext()) {
Type element = iterator.next();
// Perform operations on element
}
Explanation:
Iterator<Type>: A generic iterator object that will traverse elements of the specified type.collection.iterator(): Returns an iterator for the given collection (likeHashSet,ArrayList, etc.).hasNext(): Checks if there are more elements to iterate.next(): Retrieves the next element in the sequence.
Common Methods of Iterator Interface:
| Method | Description |
|---|---|
hasNext() | Returns true if there are more elements to iterate |
next() | Returns the next element in the iteration |
remove() | Removes the current element from the collection |
Example 1: Basic Usage with ArrayList
import java.util.ArrayList;
import java.util.Iterator;
public class IteratorExample {
public static void main(String[] args) {
ArrayList<String> students = new ArrayList<>();
students.add("Mohan");
students.add("Prakash");
students.add("Sneha");
Iterator<String> it = students.iterator();
while (it.hasNext()) {
String student = it.next();
System.out.println(student);
}
}
}
Output:
Mohan
Prakash
Sneha
Explanation
- A
studentslist is created and 3 names are added. - An
Iteratoris used to loop through each element. - Each student name is printed one by one.
- This is a basic use of
Iterator.
Example 2: Removing Elements
Let’s say we want to remove the student “Prakash” during traversal.
import java.util.ArrayList;
import java.util.Iterator;
public class RemoveExample {
public static void main(String[] args) {
ArrayList<String> students = new ArrayList<>();
students.add("Mohan");
students.add("Prakash");
students.add("Sneha");
Iterator<String> it = students.iterator();
while (it.hasNext()) {
String student = it.next();
if (student.equals("Prakash")) {
it.remove(); // Safe removal
}
}
System.out.println(students); // ✅ Corrected line
}
}
Output:
[Mohan, Sneha]
Explanation
"Prakash"is removed from the list usingit.remove()safely during iteration.- The final list is printed using
System.out.println(students). it.remove()is safe to use withIterator, unlikestudents.remove(...)which causesConcurrentModificationException.
❗ Note: Using
remove()directly from the collection during iteration (e.g.,fruits.remove(fruit)) will throwConcurrentModificationException.
Common Mistakes to Avoid
Using remove() without calling next():
Iterator<String> it = list.iterator();
it.remove(); // IllegalStateException
Always call
next()before callingremove().
Modifying the list while using a loop (without iterator):
for (String fruit : fruits) {
if (fruit.equals("Banana")) {
fruits.remove(fruit); // ConcurrentModificationException
}
}
Internal Working of Iterator
When you call iterator() on a collection, it returns an object that implements the Iterator interface.
hasNext()checks if more elements are availablenext()moves the pointer forward and returns the next elementremove()removes the last element returned bynext()
Here is a detailed Explanation
1. What Happens When You Call iterator()?
When you call:
Iterator<Type> it = collection.iterator();
- The collection (like
ArrayList,HashSet, etc.) returns an object that implements theIteratorinterface. - Each collection class has its own private internal class that implements the
Iteratorinterface.
For example:ArrayListreturns an instance of its internal classArrayList.ItrHashSetuses an iterator from its backingHashMap
2. How hasNext() Works
it.hasNext()
- Internally, the iterator maintains a cursor or index pointer.
hasNext()checks whether the cursor has reached the end of the collection.- If more elements are available, it returns
true; otherwise, it returnsfalse.
🔍 In ArrayList, the iterator maintains:
int cursor; // index of next element to return
3. How next() Works
it.next()
- If
hasNext()istrue,next():- Moves the cursor forward.
- Returns the element at the current cursor position.
- Internally stores the index of the last returned element, which is important for
remove().
🔍 In ArrayList, it looks like:
Object element = elementData[cursor];
lastRet = cursor;
cursor++;
return element;
- If
next()is called when no elements are left, it throws aNoSuchElementException.
4. How remove() Works
it.remove()
remove()deletes the last element returned bynext().- Internally, it uses the index stored in
lastRet(last returned). - After removal, it adjusts the cursor so that iteration continues smoothly.
🔒 Safety Rule:
- You must call
next()before callingremove(). - Calling
remove()withoutnext()causesIllegalStateException.
When to Use Iterator?
| Use Case | Use Iterator? |
|---|---|
| You want to traverse any collection | ✅ Yes |
| You want to remove elements during iteration | ✅ Yes |
| You need to iterate in both directions | ❌ No (Use ListIterator) |
| You want to modify elements during iteration | ❌ No (Use ListIterator or index-based loop) |
Iterator vs ListIterator
| Feature | Iterator | ListIterator |
|---|---|---|
| Traversal Direction | Forward only | Forward & Backward |
| Collections Supported | All Collections | Only Lists |
| Can Remove? | ✅ Yes | ✅ Yes |
| Can Add/Set? | ❌ No | ✅ Yes |
Example 3: Iterator with HashSet
import java.util.HashSet;
import java.util.Iterator;
public class HashSetIterator {
public static void main(String[] args) {
HashSet<Integer> numbers = new HashSet<>();
numbers.add(30);
numbers.add(50);
numbers.add(80);
Iterator<Integer> it = numbers.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
Output (Order may vary):
30
80
50
⚠️ HashSet does not maintain insertion order, but the Iterator still works on it.
Real-World Analogy
Think of a remote control that helps you go through TV channels (your collection). You press:
- Next: Go to the next channel →
next() - Check if next exists: Is there another channel? →
hasNext() - Remove channel from list: Remove that channel →
remove()
The remote is the iterator, and the TV channels are the elements of the collection.
Iterator Interface Declaration (For Reference)
public interface Iterator<E> {
boolean hasNext();
E next();
void remove(); // optional
}
Summary
| Feature | Description |
|---|---|
| Purpose | To traverse elements in a collection |
| Direction | Forward only |
| Key Methods | hasNext(), next(), remove() |
| Common Use Cases | Safe removal during iteration |
| Applicable To | List, Set, Queue, etc. |