What is an Iterator in Java
What is an iterator in Java? It is a way of looking at each element in a collection. And by collection, we mean anything in the Collection class. This includes:- ArrayList
- HashSet
- LinkedHashSet
- LinkedList
- PriorityQueue
- Vector
- and many others…

What’s the Purpose of an Iterator in Java?
Let’s face it — navigating through a collection like an ArrayList
or HashSet
can be tricky. That’s where iterators come in! But what exactly is their role?
An Iterator is like a tour guide for collections. It helps you step through the elements one by one without worrying about how the collection is structured. Sounds handy, right? Let’s break it down further.
Why Use an Iterator?
- **Universal Access:** Works with any collection that implements the
Collection
interface (e.g.,ArrayList
,HashSet
). - **Safe Removal:** Allows you to safely remove elements while iterating, avoiding
ConcurrentModificationException
. - **Simplifies Traversal:** Hides the internal structure of the collection, making it easier to navigate.
Why You Shouldn’t Use For Loops as an Iterator in Java
One of the first ways that everyone is taught to iterate through a collection in Java is for a loop. It looks like this:
class Main {
public static void main(String[] args) {
int exampleArray[] = new int[10];
//fill array with data
for(int x = 0; x < exampleArray.length; x++) {
System.out.println("Content of element " + x + "is: " + exampleArray[x]);
}
}
}
The output would be a list that reads:
Content of element 0 is: 0
Content of element 1 is: 1
Content of element 2 is: 2
etc.…
This does have its uses, but what happens if the collection doesn’t store elements in an index-based system? For example, Sets have no order normally. So it’s advisable to get out of the practice of using a for loop as an iterator in Java and practice using the Iterator<E> class instead. Here are some java iterator examples.
How to use Iterator in Java
Here are some examples of how to use iterator in Java. When using the iterator class, there are three ways to traverse a collection. You can use a while() loop, a for() loop, and a forEach() loop. Note that this for loop is different from the one we talked about before. Here are the three different java iterator examples. First, let’s set up the Collection to iterate through.
import java.util.*; // imports ArrayList, Collection and Iterator
class Main {
public static void main(String[] args) {
Collection<String> example = new ArrayList<String>();
example.add("Item 1");
example.add("Item 2");
example.add("Item 3");
example.add("Item 4");
}
}
This is a simple Collection made up of an ArrayList to which we loaded four items. Now let’s look at the three methods of using the Iterator class to traverse the ArrayList.
While() loop
Iterator<String> iterator = example.iterator();
while (iterator.hasNext()) {
System.out.println("Element Value= " + iterator.next());
}
This while() loop uses the .hasNext() Boolean method of the Iterator class to check to see if there is a future element. If the precondition is true, then it proceeds. If it returns as false, then the loop ends. The key part here is that the .hasNext() and the .next() methods both do an initial check of the first element. If the Collection is empty and there is no first element, then the method returns false for the .hasNext() and will throw a NoSuchElementException for the .next() method.
For loop
for (Iterator<String> iterator = example.iterator(); iterator.hasNext();) {
System.out.println("Element Value= " + iterator.next());
}
This looks like a more traditional for loop. It uses the .hasNext() method as the condition check and change portion. The initialization is the call to the Iterator.
For:Each loop
for (String s : example) {
System.out.println("Element Value= " + s);
}
The For:Each loop is a for loop, but if you don’t know how to read it, it may be a little confusing. The syntax of a For:Each loop is for (data_type variableName : collectionName){ body}. This for:each loop does have a couple of drawbacks. First, it can only traverse the collection in one direction. Second, you have to iterate through each element. You can’t skip any of them. But as a convenient list iterator in Java, it’s the best option.
On the plus side, the for:each loop is very easy to read and once you know it, it’s difficult to get wrong.
If you’re wondering what the output of the three iterator loops is, they are all the same:
Element Value= Item 1
Element Value= Item 2
Element Value= Item 3
Element Value= Item 4
How to use an Iterator in Java For Maps
Maps are a popular way to store data, but because they don’t extend Collection, you can’t use the previous iterators to directly traverse a map. So how do you use an iterator in Java to go through Maps and HashMaps? There are four good Java map iterator methods. We’ll cover them individually. First, let’s load a map with a series of values.
import java.util.*; //imports Map and HashMap
class Main {
public static void main(String[] args) {
Map<String, String> example = new HashMap<String, String>();
example.put("alpha", "one");
example.put("beta", "two");
example.put("gamma", "three");
}
}
Java Hashmap Iterator Method: forEach(action)
example.forEach((k,v) -> System.out.println("Key: "+ k + ", Value: " + v));
This method uses a lambda expression to iterate through. The lambda operator is the forEach() method, and the body prints out the values. This uses a multiple parameter operator. This is the fastest and cleanest method for map iterator in Java 8.
Java Hashmap Iterator Method: For:Each() Loop
for (Map.Entry<String, String> iterate : example.entrySet()) {
System.out.println("Key: " + iterate.getKey() + ", Value: " + iterate.getValue());
}
This uses the For:Each syntax to call the entrySet() method to return a set that has the key and value as its elements. Additionally, when using the .Entry() method, the objects are only true while this iteration is occurring.
Java Hashmap Iterator Method: Map.Entry<k, v>
Iterator<Map.Entry<String, String>> iterator = example.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry<String, String> element = iterator.next();
System.out.println("Key: " + element.getKey() + ", Value: " + element.getValue());
)
This method again converts the Map to a set to use the Collections Iterator and methods. For these three iterator methods, the return looks like this:
Key: alpha, Value: one
Key: beta, Value: two
Key: gamma, Value: three
Java Hashmap Iterator Method: keySet() and values()
for (String key : example.keySet()) {
System.out.println("Key: " + key);
}
for (String value : example.values()) {
System.out.println("Value: " + value);
}
This one returns the elements in a different way. It will first return all of the Keys in order and then all of the Values:
Key: alpha
Key: beta
Key: gamma
Value: one
Value: two
Value: three
How Does an Iterator Work Internally?
Okay, but how does this "tour guide" know where it’s going? Let’s peek under the hood and explore how iterators actually work!
Internal Mechanism
Internally, an iterator maintains a cursor that points to the current position in the collection. Every time you call next()
, the cursor moves forward.
hasNext()
→ Checks if there’s another element ahead.next()
→ Moves the cursor and returns the current element.remove()
→ Removes the last element returned bynext()
.
Example: Simulating an Iterator
Here’s a simplified version of how an iterator might work inside an ArrayList
.
class SimpleIterator {
private T[] data;
private int cursor = 0;
public SimpleIterator(T[] data) {
this.data = data;
}
public boolean hasNext() {
return cursor < data.length;
}
public T next() {
return data[cursor++];
}
}
public class CustomIteratorDemo {
public static void main(String[] args) {
String[] items = {"Pen", "Notebook", "Eraser"};
SimpleIterator iterator = new SimpleIterator<>(items);
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
Output:
Pen
Notebook
Eraser
See? That’s how iterators internally manage traversal—just by keeping track of the current position. Simple but effective!
Iterator vs. Enhanced For Loop
You might wonder, "Why not just use a for-each
loop?" Great question! The enhanced for-loop is great for reading data, but what if you need to remove elements while looping? That’s where iterators shine!
Enhanced For Loop Limitation
List names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
for (String name : names) {
if (name.equals("Bob")) {
// names.remove(name); // Throws ConcurrentModificationException!
}
}
Iterator to the Rescue!
Iterator itr = names.iterator();
while (itr.hasNext()) {
if (itr.next().equals("Bob")) {
itr.remove(); // Safe removal
}
}
Lesson learned? Use iterators when you need to modify a collection while looping through it!
You’ve already learned how to use iterators to loop through collections. But here’s the real deal — did you know that you can safely remove elements while iterating? Yep, it’s totally possible, and we’re going to break it down
The Problem with Removing Elements in a Loop
Imagine you’re iterating through a list and want to remove some elements. If you try to do it with a regular loop, Java might not be too happy about it…
Example: Using a For-Each Loop (Don’t Do This!)
import java.util.ArrayList;
import java.util.List;
public class UnsafeRemoval {
public static void main(String[] args) {
List names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
for (String name : names) {
if (name.equals("Bob")) {
names.remove(name); // Uh-oh! This will throw an exception!
}
}
}
}
Output:
Exception in thread "main" java.util.ConcurrentModificationException
Oops! That’s a ConcurrentModificationException
. But why?
When you modify a collection directly (like calling remove()
) while iterating over it, Java throws this exception to prevent unpredictable behavior. So, how do we fix this? Enter the mighty Iterator.remove()
!
The Right Way: Using Iterator.remove()
The Iterator
interface gives you a safe and easy way to remove elements during iteration. Let’s see how it works!
Example: Safe Removal with Iterator.remove()
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class SafeRemoval {
public static void main(String[] args) {
List names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
Iterator iterator = names.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
if (name.equals("Bob")) {
iterator.remove(); // Safe removal
}
}
System.out.println(names);
}
}
Output:
[Alice, Charlie]
And just like that, Bob is gone! No exceptions, no drama.
Quick Recap
- **Never remove elements directly during iteration**—it leads to
ConcurrentModificationException
. - Use
Iterator.remove()
**after callingnext()
** to safely remove elements. - **Don’t call
remove()
beforenext()
**—this will throw anIllegalStateException
.
GO TO FULL VERSION