0
Explore
0

Iterator in Java Collection – A Complete Guide

Updated on August 1, 2025

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, and LinkedHashSet do 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 or ArrayList where elements are accessed by index.

    ❌ You can’t do set.get(i) with a HashSet – 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 for loop or enhanced for-each loop, if you try to remove an element from the collection during iteration, it throws a ConcurrentModificationException.

    ❌ You cannot safely remove elements using set.remove() inside a for or for-each loop.

    4. No Flexibility in Traversal

    • The for loop 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 (like HashSet, ArrayList, etc.).
    • hasNext(): Checks if there are more elements to iterate.
    • next(): Retrieves the next element in the sequence.

    Common Methods of Iterator Interface:

    MethodDescription
    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 students list is created and 3 names are added.
    • An Iterator is 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 using it.remove() safely during iteration.
    • The final list is printed using System.out.println(students).
    • it.remove() is safe to use with Iterator, unlike students.remove(...) which causes ConcurrentModificationException.

    Note: Using remove() directly from the collection during iteration (e.g., fruits.remove(fruit)) will throw ConcurrentModificationException.

    Common Mistakes to Avoid

    Using remove() without calling next():

    Iterator<String> it = list.iterator();
    it.remove(); // IllegalStateException

    Always call next() before calling remove().

    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 available
    • next() moves the pointer forward and returns the next element
    • remove() removes the last element returned by next()

    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 the Iterator interface.
    • Each collection class has its own private internal class that implements the Iterator interface.
      For example:
      • ArrayList returns an instance of its internal class ArrayList.Itr
      • HashSet uses an iterator from its backing HashMap

    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 returns false.

    🔍 In ArrayList, the iterator maintains:

    int cursor; // index of next element to return

    3. How next() Works

    it.next()
    • If hasNext() is true, next():
      1. Moves the cursor forward.
      2. Returns the element at the current cursor position.
      3. 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 a NoSuchElementException.

    4. How remove() Works

    it.remove()
    • remove() deletes the last element returned by next().
    • 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 calling remove().
    • Calling remove() without next() causes IllegalStateException.

    When to Use Iterator?

    Use CaseUse 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

    FeatureIteratorListIterator
    Traversal DirectionForward onlyForward & Backward
    Collections SupportedAll CollectionsOnly 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

    FeatureDescription
    PurposeTo traverse elements in a collection
    DirectionForward only
    Key MethodshasNext(), next(), remove()
    Common Use CasesSafe removal during iteration
    Applicable ToList, Set, Queue, etc.