CodeToConcept
About

java

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

Sample Question

Think it through, then check the tutorial.

CodeToConcept

Quickly learn through simple, structured, and practical coding tutorials. Build your confidence from step zero to real-world experience.

© 2026 CodeToConcept. All rights reserved.

Quick Links

AboutTutorials

Tutorials

JavaHTMLCSS

Support

Privacy PolicyTerms of ServiceContact
GitHubTwitterYouTube

Java Collections Framework - Iterator

An Iterator in Java is an object used to traverse or iterate through the elements of a collection one by one.

It provides a common way to access elements from collections such as:

  • ArrayList
  • LinkedList
  • HashSet
  • LinkedHashSet
  • TreeSet
  • and many other collection classes

The Iterator interface is available in the java.util package.

import java.util.Iterator;

Why do we use Iterator?

Different collection classes may store their elements differently.

For example:

  • ArrayList stores elements using indexes.
  • HashSet does not provide index-based access.
  • TreeSet maintains elements according to their ordering.

Instead of learning a different traversal mechanism for every collection, Java provides the Iterator interface.

It provides a common way to move through collection elements.

Basic Example

Consider an ArrayList:

import java.util.ArrayList;
import java.util.Iterator;
 
public class HelloWorld {
    public static void main(String[] args) {
 
        ArrayList<String> languages = new ArrayList<>();
 
        languages.add("Java");
        languages.add("Python");
        languages.add("C++");
 
        Iterator<String> iterator = languages.iterator();
 
        while (iterator.hasNext()) {
            String language = iterator.next();
            System.out.println(language);
        }
    }
}

Output

Java
Python
C++

How Iterator Works

The basic process is:

Collection
    ↓
iterator()
    ↓
Iterator object
    ↓
hasNext()
    ↓
next()
    ↓
Next element

For example:

Iterator<String> iterator = languages.iterator();

This creates an iterator for the collection.

Then:

iterator.hasNext()

checks whether another element is available.

If an element exists:

iterator.next()

returns the next element.

Important Iterator Methods

The Iterator interface mainly provides the following methods:

MethodPurpose
hasNext()Checks whether another element exists
next()Returns the next element
remove()Removes the last element returned by the iterator
forEachRemaining()Performs an action on remaining elements

Let's understand them one by one.

1. hasNext()

The hasNext() method checks whether there is another element available.

It returns:

true

if another element exists.

Otherwise, it returns:

false

Example

Iterator<String> iterator = languages.iterator();
 
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

The loop continues as long as another element is available.

Why is hasNext() important?

Calling next() when there are no more elements can result in a NoSuchElementException.

Therefore, it is common to check:

iterator.hasNext()

before calling:

iterator.next()

2. next()

The next() method returns the next element from the collection.

Example

Iterator<String> iterator = languages.iterator();
 
System.out.println(iterator.next());
System.out.println(iterator.next());

If the collection contains:

Java
Python
C++

the output will be:

Java
Python

The iterator maintains its current position as it moves through the collection.

3. remove()

The remove() method removes the last element returned by the iterator, if that iterator supports removal. It is an optional operation; unsupported removal throws UnsupportedOperationException.

Example

ArrayList<String> languages = new ArrayList<>();
 
languages.add("Java");
languages.add("Python");
languages.add("C++");
 
Iterator<String> iterator = languages.iterator();
 
while (iterator.hasNext()) {
 
    String language = iterator.next();
 
    if (language.equals("Python")) {
        iterator.remove();
    }
}
 
System.out.println(languages);

Output

[Java, C++]

Why use Iterator.remove()?

Removing elements directly from a collection while using an iterator can cause a ConcurrentModificationException for many collection implementations.

For example, this pattern should generally be avoided:

for (String language : languages) {
 
    if (language.equals("Python")) {
        languages.remove(language);
    }
}

Instead, use the iterator's remove() method when performing removal during iterator traversal:

Iterator<String> iterator = languages.iterator();
 
while (iterator.hasNext()) {
 
    String language = iterator.next();
 
    if (language.equals("Python")) {
        iterator.remove();
    }
}

Important Rule for remove()

remove() removes the element returned by the most recent next() call.

For iterators supporting removal, calling remove() before next() is invalid. Calling it twice after a single next() call is also invalid.

For example:

Iterator<String> iterator = languages.iterator();
 
iterator.remove();

This can result in an IllegalStateException.

4. forEachRemaining()

The forEachRemaining() method performs an action on all remaining elements.

Example

Iterator<String> iterator = languages.iterator();
 
iterator.forEachRemaining(
    language -> System.out.println(language)
);

This processes the elements that have not yet been consumed by the iterator.

Iterator with ArrayList

Example

ArrayList<Integer> numbers = new ArrayList<>();
 
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);
 
Iterator<Integer> iterator = numbers.iterator();
 
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

Output

10
20
30
40

Iterator with HashSet

One important advantage of Iterator is that it can also be used with collections that do not provide index-based access.

For example:

HashSet<String> languages = new HashSet<>();
 
languages.add("Java");
languages.add("Python");
languages.add("C++");
 
Iterator<String> iterator = languages.iterator();
 
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

This is useful because HashSet does not provide methods such as:

get(0)
get(1)
get(2)

like an ArrayList.

Iterator with LinkedHashSet

LinkedHashSet<String> languages =
    new LinkedHashSet<>();
 
languages.add("Java");
languages.add("Python");
languages.add("C++");
 
Iterator<String> iterator =
    languages.iterator();
 
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

Since LinkedHashSet maintains insertion order, iteration follows that order.

Iterator with TreeSet

Iterator can also be used with TreeSet.

TreeSet<Integer> numbers = new TreeSet<>();
 
numbers.add(30);
numbers.add(10);
numbers.add(20);
 
Iterator<Integer> iterator =
    numbers.iterator();
 
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

Output

10
20
30

The TreeSet maintains its sorted ordering, so the iterator encounters elements according to that ordering.

Iterator with Map

There is an important difference between Collection and Map.

A Map does not directly provide an iterator() method.

For example, this is not valid:

Map<Integer, String> map = new HashMap<>();
 
Iterator<Integer> iterator = map.iterator();

Instead, we can obtain an iterator from the Map's collection views.

Iterating Through Map Entries

Map<Integer, String> map = new HashMap<>();
 
map.put(101, "Ashish");
map.put(102, "Rahul");
map.put(103, "Priya");
 
Iterator<Map.Entry<Integer, String>> iterator =
    map.entrySet().iterator();
 
while (iterator.hasNext()) {
 
    Map.Entry<Integer, String> entry =
        iterator.next();
 
    System.out.println(
        entry.getKey() + " -> " + entry.getValue()
    );
}

Iterating Through Map Keys

Iterator<Integer> iterator =
    map.keySet().iterator();
 
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

Iterating Through Map Values

Iterator<String> iterator =
    map.values().iterator();
 
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

Iterator vs Enhanced for Loop

Java also provides the enhanced for loop:

for (String language : languages) {
    System.out.println(language);
}

This is often simpler than using an iterator explicitly.

The enhanced for loop internally uses an iterator for Iterable collections.

When should we use Iterator?

An explicit Iterator is particularly useful when:

  • We need to remove elements during traversal.
  • We need direct control over traversal.
  • We are working with collections that do not support index-based access.
  • We need iterator-specific behavior.

For simple traversal, the enhanced for loop is often easier to read.

Iterator vs ListIterator

Java also provides another interface called ListIterator.

The main difference is that Iterator generally moves in one direction, while ListIterator provides additional functionality for lists.

IteratorListIterator
Works with collections through iterator()Designed specifically for List
Mainly moves forwardCan move forward and backward
hasNext()hasNext() and hasPrevious()
next()next() and previous()
Can removeCan remove
Cannot directly add elementsCan add elements
Cannot directly replace elementsCan replace elements using set()

Example

ListIterator<String> iterator =
    languages.listIterator();

ListIterator is useful when working specifically with lists and needing bidirectional traversal.

Iterator and ConcurrentModificationException

A common problem when modifying a collection during iteration is:

ConcurrentModificationException

For example:

for (String language : languages) {
 
    if (language.equals("Python")) {
        languages.remove(language);
    }
}

This can cause a ConcurrentModificationException.

A safer approach for iterator-based removal is:

Iterator<String> iterator =
    languages.iterator();
 
while (iterator.hasNext()) {
 
    String language = iterator.next();
 
    if (language.equals("Python")) {
        iterator.remove();
    }
}

Important Note

Iterator.remove() is the iterator-supported way to remove the element most recently returned by that iterator.

However, the exact behavior of concurrent modifications can depend on the collection implementation. Many standard Java collections use fail-fast iterators, which detect certain structural modifications and may throw ConcurrentModificationException.

Complete Example

import java.util.ArrayList;
import java.util.Iterator;
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        ArrayList<String> languages =
            new ArrayList<>();
 
        languages.add("Java");
        languages.add("Python");
        languages.add("C++");
        languages.add("JavaScript");
 
        Iterator<String> iterator =
            languages.iterator();
 
        while (iterator.hasNext()) {
 
            String language = iterator.next();
 
            if (language.equals("Python")) {
                iterator.remove();
            }
        }
 
        System.out.println(languages);
    }
}

Output

[Java, C++, JavaScript]

Advantages of Iterator

1. Common Traversal Mechanism

Iterator provides a standard way to traverse many different collection types.

2. Works Without Indexes

It can be used with collections such as HashSet that do not provide index-based access.

3. Safe Removal During Traversal

Its remove() method provides a supported way to remove the last returned element.

4. Simple Traversal

The combination of:

hasNext()

and:

next()

makes collection traversal straightforward.

Limitations of Iterator

  • It generally moves only in the forward direction.
  • It does not provide index-based access.
  • It cannot directly add an element.
  • It cannot directly replace an element.

For lists requiring forward and backward traversal, ListIterator is more suitable.

Important Points

  • Iterator is an interface in java.util.
  • It is used to traverse collection elements.
  • hasNext() checks whether another element exists.
  • next() returns the next element.
  • remove() removes the last element returned by next().
  • forEachRemaining() processes remaining elements.
  • Iterator can be used with lists, sets, and collection views of maps.
  • A Map itself does not directly provide an iterator.
  • entrySet(), keySet(), or values() can be used to obtain an iterator from a Map.
  • ListIterator provides additional functionality for lists.
  • Modifying a collection directly while iterating can result in ConcurrentModificationException.
  • For iterator-based removal, use Iterator.remove().

Key Takeaway

An Iterator provides a standard way to traverse elements of a collection one by one.

The most commonly used pattern is:

Iterator<String> iterator =
    collection.iterator();
 
while (iterator.hasNext()) {
 
    String value = iterator.next();
 
    System.out.println(value);
}

When elements need to be removed during traversal:

if (condition) {
    iterator.remove();
}

Understanding Iterator is important because it forms one of the fundamental mechanisms for traversing Java collections.

See you in next page....🙂

← HashtableComparable & Comparator →
← HashtableComparable & Comparator →