← Back to Core Java Course | Chapter 11: Collections | Lesson 15 of 17

Java Iterator

Introduction to Iterator

Iterator provides a uniform way to step through any collection one element at a time via hasNext() and next(), without needing to know whether the underlying collection is a List, Set, or something else.

Example: Introduction to Iterator

java
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<>(java.util.List.of("a", "b"));
		Iterator<String> it = list.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}
	}
}

Removing Elements with Iterator

Calling iterator.remove() during iteration safely deletes the current element from the underlying collection — this is the only safe way to remove elements while looping, since modifying the collection directly mid-loop throws a ConcurrentModificationException.

Example: Removing Elements with Iterator

java
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
	public static void main(String[] args) {
		ArrayList<Integer> list = new ArrayList<>(java.util.List.of(1, 2, 3, 4));
		Iterator<Integer> it = list.iterator();
		while (it.hasNext()) {
			if (it.next() % 2 == 0) {
				it.remove(); // safe removal during iteration
			}
		}
		System.out.println(list);
	}
}

Iterator on Set

A Set has no indexed access, so Iterator is often the only practical way to visit every element in order, since you can't use a traditional indexed for loop the way you could with a List.

Example: Iterator on Set

java
import java.util.HashSet;
import java.util.Iterator;
public class Main {
	public static void main(String[] args) {
		HashSet<String> set = new HashSet<>(java.util.List.of("a", "b"));
		Iterator<String> it = set.iterator(); // no indexed access on a Set
		while (it.hasNext()) {
			System.out.println(it.next());
		}
	}
}

ListIterator (Bidirectional)

ListIterator extends Iterator with the ability to move backward (hasPrevious()/previous()) and to replace or insert elements mid-traversal, capabilities plain Iterator doesn't offer.

Example: ListIterator (Bidirectional)

java
import java.util.ArrayList;
import java.util.ListIterator;
public class Main {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<>(java.util.List.of("a", "b"));
		ListIterator<String> it = list.listIterator();
		while (it.hasNext()) it.next();
		while (it.hasPrevious()) {
			System.out.println(it.previous()); // moves backward
		}
	}
}

Safe Modification

Modifying a collection any way other than through the iterator's own methods while iterating (e.g. calling list.remove() directly inside a for-each loop) throws ConcurrentModificationException — always go through the iterator itself for safe mutation.

Example: Safe Modification

java
import java.util.ArrayList;
public class Main {
	public static void main(String[] args) {
		ArrayList<Integer> list = new ArrayList<>(java.util.List.of(1, 2, 3));
		try {
			for (Integer n : list) {
				list.remove(n); // direct modification during for-each
			}
		} catch (java.util.ConcurrentModificationException e) {
			System.out.println("Caught: " + e.getClass().getSimpleName());
		}
	}
}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.