An Iterator is an interface in the Java Collections
Framework that allows you to access elements one by one.
It is commonly used to traverse collections such as ArrayList,
HashSet, and other collections that support iteration.
An Iterator lets you move through a collection without needing to manage indexes manually.
For example, consider this list:
[10, 20, 30, 40, 50]
An Iterator can visit each element and display it. It is particularly useful for collections that do not provide index-based access.
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
Iterator<Integer> iterator = numbers.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
Output:
10
20
30
The iterator() method returns an Iterator
for a collection.
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
names.add("Rahul");
names.add("Amit");
names.add("Priya");
Iterator<String> it = names.iterator();
System.out.println(it.next());
}
}
Output:
Rahul
The iterator() method creates an iterator,
and next() returns the next element.
Calling next() when no elements remain
causes a NoSuchElementException.
The hasNext() method checks whether another
element is available. It returns true if
an element remains and false otherwise.
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
ArrayList<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Mango");
fruits.add("Banana");
Iterator<String> it = fruits.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
Output:
Apple
Mango
Banana
Always check hasNext() before calling
next() in a normal iteration loop.
The next() method returns the next element
and advances the iterator.
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(100);
numbers.add(200);
numbers.add(300);
Iterator<Integer> it = numbers.iterator();
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next());
}
}
Output:
100
200
300
next() after all elements have
been consumed throws NoSuchElementException.
The remove() method removes the last element
returned by the iterator. It is useful when removing
elements while traversing a collection.
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);
Iterator<Integer> it = numbers.iterator();
while (it.hasNext()) {
int number = it.next();
if (number == 20) {
it.remove();
}
}
System.out.println(numbers);
}
}
Output:
[10, 30, 40]
Call remove() only after calling
next(), and do not call it twice for the
same returned element.
Iterators are useful with HashSet because HashSet does not provide index-based access.
import java.util.HashSet;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
HashSet<String> cities = new HashSet<>();
cities.add("Delhi");
cities.add("Patna");
cities.add("Mumbai");
Iterator<String> it = cities.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
The program displays all three cities, but their order is not guaranteed because HashSet does not guarantee iteration order.
An Iterator can traverse a list of strings just as easily as a list of numbers.
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
ArrayList<String> subjects = new ArrayList<>();
subjects.add("Java");
subjects.add("Python");
subjects.add("JavaScript");
subjects.add("PHP");
Iterator<String> it = subjects.iterator();
while (it.hasNext()) {
String subject = it.next();
System.out.println("Subject: " + subject);
}
}
}
Output:
Subject: Java
Subject: Python
Subject: JavaScript
Subject: PHP
Both approaches can traverse a collection, but they offer different levels of control.
| Iterator | For-each Loop |
|---|---|
Uses iterator(), hasNext(), and next(). |
Uses a concise loop syntax. |
Supports removal through Iterator.remove(). |
Does not directly provide iterator removal. |
| Useful when elements must be conditionally removed. | Useful for straightforward traversal. |
| Works with collections that provide an Iterator. | Works with arrays and Iterable objects. |
For-each example:
for (String name : names) {
System.out.println(name);
}
ListIterator is available for lists and can
traverse in both forward and backward directions. It also
supports adding, replacing, and removing elements.
import java.util.ArrayList;
import java.util.ListIterator;
public class Main {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
names.add("Rahul");
names.add("Amit");
names.add("Priya");
ListIterator<String> it = names.listIterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println("Backward:");
while (it.hasPrevious()) {
System.out.println(it.previous());
}
}
}
Output:
Rahul
Amit
Priya
Backward:
Priya
Amit
Rahul
Unlike a regular Iterator, ListIterator supports
hasPrevious() and previous().
Many collection iterators are fail-fast. If a collection
is structurally modified outside the iterator while
iteration is in progress, the iterator may throw a
ConcurrentModificationException.
Avoid removing elements directly inside a for-each loop:
// Avoid this pattern:
for (String name : names) {
if (name.equals("Amit")) {
names.remove(name);
}
}
Use the iterator's remove method instead:
Iterator<String> it = names.iterator();
while (it.hasNext()) {
if (it.next().equals("Amit")) {
it.remove();
}
}
| Method | Purpose |
|---|---|
iterator() |
Returns an iterator from a collection. |
hasNext() |
Checks whether another element is available. |
next() |
Returns the next element. |
remove() |
Removes the last returned element when supported. |
forEachRemaining() |
Performs an action on remaining elements. |
Example of forEachRemaining():
Iterator<String> it = names.iterator();
it.forEachRemaining(System.out::println);
This program uses an Iterator to remove all even numbers from an ArrayList.
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(15);
numbers.add(20);
numbers.add(25);
numbers.add(30);
Iterator<Integer> it = numbers.iterator();
while (it.hasNext()) {
int number = it.next();
if (number % 2 == 0) {
it.remove();
}
}
System.out.println(numbers);
}
}
Output:
[15, 25]
The condition number % 2 == 0 identifies
even numbers. The iterator removes each matching element
safely during traversal.
1. Which method checks whether another element is available?
2. Which Iterator method removes the last returned element?
3. Which interface supports backward traversal of a List?