DEV Community

realNameHidden
realNameHidden

Posted on

🔄 What’s the Difference Between Iterator and ListIterator in Java?

Learn the key differences between Iterator and ListIterator in Java with clear explanations, examples, and best practices to master safe and efficient list traversal.


🏁 Introduction

Imagine you’re flipping through a photo album — one page at a time, from the start to the end. That’s how an Iterator works in Java. But what if you could also flip backward, jump to a specific photo, or replace one? That’s where ListIterator comes in!

In Java programming, iterators are essential tools for traversing collections safely — especially when you want to avoid issues like ConcurrentModificationException. Understanding the difference between Iterator and ListIterator helps you choose the right tool for the job and write cleaner, more efficient code.

Let’s explore both, see how they work, and compare them side by side with easy examples.


💡 Core Concepts

🔹 What is an Iterator?

An Iterator is like a one-way cursor that lets you move through elements in a collection, such as an ArrayList or HashSet.
You can only move forward and remove elements during iteration.

  • Belongs to the java.util package.
  • Works with all collection types (e.g., Set, List, Queue).
  • Provides methods like:

    • hasNext() → checks if there are more elements.
    • next() → returns the next element.
    • remove() → removes the current element from the collection.

Iterator is best when you just need to read or remove elements in one direction.


🔹 What is a ListIterator?

A ListIterator is a more powerful version of Iterator, designed exclusively for List collections like ArrayList and LinkedList.

Unlike Iterator, it allows you to:

  • Move forward and backward.
  • Add, remove, or modify elements during iteration.
  • Get index positions of elements while iterating.

ListIterator is ideal when you need bi-directional navigation or want to update a list dynamically while traversing it.


🔸 Key Differences at a Glance

Feature Iterator ListIterator
Traversal Direction Forward only Forward and backward
Applicable Collections Works with all collections Works only with Lists
Add/Set Element Not supported Supported (add(), set())
Access Index Not available Can access next/previous index
Initial Position Before the first element Can start at any index
Performance Lightweight Slightly heavier due to extra features

Think of Iterator as a “simple radio” — plays songs forward.
ListIterator is like a “smart music player” — you can skip, rewind, or even replace a song mid-play!


💻 Code Examples

✅ Example 1: Using Iterator (Forward Traversal Only)

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorExample {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("Amit");
        names.add("Bina");
        names.add("Chetan");

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

        System.out.println("Traversing using Iterator:");
        while (iterator.hasNext()) {
            String name = iterator.next();
            System.out.println(name);

            // Removing element safely during iteration
            if (name.equals("Bina")) {
                iterator.remove();
            }
        }

        System.out.println("List after removal: " + names);
    }
}
Enter fullscreen mode Exit fullscreen mode

🧩 Explanation:

  • The Iterator moves forward one element at a time using next().
  • We safely removed “Bina” during iteration using iterator.remove().
  • Removing directly from the list (names.remove()) here would cause a ConcurrentModificationException.

✅ Example 2: Using ListIterator (Bi-Directional and Editable Traversal)

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorExample {
    public static void main(String[] args) {
        List<String> languages = new ArrayList<>();
        languages.add("Java");
        languages.add("Python");
        languages.add("C++");

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

        System.out.println("Forward Traversal:");
        while (listIterator.hasNext()) {
            String lang = listIterator.next();
            System.out.println(lang);

            // Modify element
            if (lang.equals("Python")) {
                listIterator.set("Kotlin"); // replace Python with Kotlin
            }
        }

        System.out.println("\nBackward Traversal:");
        while (listIterator.hasPrevious()) {
            System.out.println(listIterator.previous());
        }

        System.out.println("\nUpdated List: " + languages);
    }
}
Enter fullscreen mode Exit fullscreen mode

🧩 Explanation:

  • The ListIterator can move both ways using hasNext()/next() and hasPrevious()/previous().
  • You can modify elements using set() and even insert new ones using add().
  • Perfect when working with lists where you need flexibility.

🧠 Best Practices

  1. Prefer Iterator for simplicity.
    If you only need forward traversal and element removal, Iterator is lightweight and efficient.

  2. Use ListIterator for lists with editing needs.
    When modifying elements during iteration or traversing both directions, ListIterator is your best friend.

  3. Avoid modifying the collection directly.
    Always use remove() or set() from the iterator to prevent ConcurrentModificationException.

  4. Initialize ListIterator at the right position.
    You can start it from a specific index (list.listIterator(index)) — handy for partial traversals.

  5. Don’t use Iterator on concurrent collections carelessly.
    Use CopyOnWriteArrayList or ConcurrentHashMap iterators for thread-safe operations.


🏁 Conclusion

In Java programming, Iterator and ListIterator may look similar, but they serve different needs:

  • Use Iterator when you only need forward traversal across any collection.
  • Use ListIterator when working with lists that require updates, additions, or reverse traversal.

By mastering both, you’ll be able to handle collections efficiently and avoid common pitfalls like concurrent modification errors. Remember: choosing the right iterator can make your code cleaner, safer, and easier to maintain.


Top comments (0)