Skip to main content

Java Iterator

Table of Contents

What is an Iterator?

An Iterator is an object that provides a standard way to traverse (loop through) collections in Java, such as:

  • ArrayList
  • HashSet
  • LinkedList
  • Vector
  • And other Collection Framework classes

💡 Etymology: The term "iterator" comes from "iterating," which is the technical term for looping or repeating through elements.

Import Statement

import java.util.Iterator;

Key Concepts

1. Sequential Access

  • Iterators provide sequential access to collection elements
  • You can move forward through the collection one element at a time
  • Cannot move backward (unless using ListIterator)

2. Fail-Safe Iteration

  • Safe way to modify collections during iteration
  • Prevents ConcurrentModificationException when removing elements

3. Generic Type Support

Iterator<String> stringIterator;
Iterator<Integer> integerIterator;
Iterator<CustomObject> objectIterator;

Getting an Iterator

Every collection class provides an iterator() method:

// Basic syntax
Iterator<DataType> iteratorName = collection.iterator();

// Examples
ArrayList<String> list = new ArrayList<>();
Iterator<String> it = list.iterator();

HashSet<Integer> set = new HashSet<>();
Iterator<Integer> numIt = set.iterator();

Core Methods

MethodReturn TypeDescription
hasNext()booleanReturns true if there are more elements
next()E (generic)Returns the next element and advances the iterator
remove()voidRemoves the last element returned by next()

Method Details

hasNext()

  • Purpose: Check if more elements exist
  • Usage: Typically used in loop conditions
  • Returns: true if iteration has more elements

next()

  • Purpose: Retrieve the next element
  • Side Effect: Advances the iterator position
  • Throws: NoSuchElementException if no more elements exist

remove()

  • Purpose: Safely remove elements during iteration
  • Important: Can only be called once per next() call
  • Throws: IllegalStateException if called before next() or called twice

Looping Through Collections

Basic Iteration Pattern

while (iterator.hasNext()) {
DataType element = iterator.next();
// Process the element
System.out.println(element);
}

Complete Example

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

public class IteratorExample {
public static void main(String[] args) {
ArrayList<String> cars = new ArrayList<>();
cars.add("Volvo");
cars.add("BMW");
cars.add("Ford");
cars.add("Mazda");

Iterator<String> it = cars.iterator();

while (it.hasNext()) {
String car = it.next();
System.out.println(car);
}
}
}

Removing Items Safely

❌ Incorrect Way (Using Enhanced For Loop)

// This can cause ConcurrentModificationException
for (Integer num : numbers) {
if (num < 10) {
numbers.remove(num); // DANGEROUS!
}
}

✅ Correct Way (Using Iterator)

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

public class SafeRemoval {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(12);
numbers.add(8);
numbers.add(2);
numbers.add(23);

Iterator<Integer> it = numbers.iterator();
while (it.hasNext()) {
Integer num = it.next();
if (num < 10) {
it.remove(); // Safe removal
}
}

System.out.println(numbers); // Output: [12, 23]
}
}

Best Practices

1. Always Use hasNext() Before next()

// Good practice
while (it.hasNext()) {
String element = it.next();
// Process element
}

// Avoid calling next() without checking

2. Handle Exceptions Properly

try {
while (it.hasNext()) {
String element = it.next();
// Process element
}
} catch (NoSuchElementException e) {
System.err.println("Iterator exhausted: " + e.getMessage());
}

3. Use Enhanced For Loop When Not Modifying

// When you don't need to remove elements, use enhanced for loop
for (String car : cars) {
System.out.println(car);
}

4. Don't Reuse Iterators

// Create a new iterator for each iteration cycle
Iterator<String> it1 = list.iterator();
// Use it1...

// Later, create a new one
Iterator<String> it2 = list.iterator();
// Use it2...

Common Pitfalls

1. Calling remove() Before next()

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

// ✅ Correct
Iterator<String> it = list.iterator();
if (it.hasNext()) {
it.next();
it.remove(); // Now it's safe
}

2. Multiple remove() Calls

// ❌ Wrong
String element = it.next();
it.remove();
it.remove(); // IllegalStateException!

// ✅ Correct
String element = it.next();
it.remove(); // Only one remove() per next()

3. Modifying Collection Directly During Iteration

// ❌ Wrong - Can cause ConcurrentModificationException
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String element = it.next();
list.add("New Element"); // Direct modification!
}

// ✅ Correct - Use iterator methods only
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String element = it.next();
it.remove(); // Use iterator's remove method
}

Advanced Usage

Working with Different Collection Types

ArrayList Example

ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("A");
arrayList.add("B");
arrayList.add("C");

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

HashSet Example

HashSet<Integer> hashSet = new HashSet<>();
hashSet.add(10);
hashSet.add(20);
hashSet.add(30);

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

Custom Object Iteration

class Person {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public String toString() {
return name + " (" + age + ")";
}
}

// Usage
ArrayList<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));

Iterator<Person> personIt = people.iterator();
while (personIt.hasNext()) {
Person person = personIt.next();
System.out.println(person);
}

Code Examples

Example 1: Basic Iteration

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

public class BasicIteration {
public static void main(String[] args) {
ArrayList<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");

Iterator<String> it = fruits.iterator();

System.out.println("Fruits in the list:");
while (it.hasNext()) {
System.out.println("- " + it.next());
}
}
}

Example 2: Conditional Processing

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

public class ConditionalProcessing {
public static void main(String[] args) {
ArrayList<Integer> scores = new ArrayList<>();
scores.add(95);
scores.add(67);
scores.add(88);
scores.add(45);
scores.add(92);

Iterator<Integer> it = scores.iterator();

System.out.println("High scores (80 and above):");
while (it.hasNext()) {
Integer score = it.next();
if (score >= 80) {
System.out.println("Score: " + score);
}
}
}
}

Example 3: Filtering and Removal

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

public class FilterAndRemove {
public static void main(String[] args) {
ArrayList<String> words = new ArrayList<>();
words.add("hello");
words.add("a");
words.add("world");
words.add("of");
words.add("programming");

System.out.println("Original list: " + words);

Iterator<String> it = words.iterator();
while (it.hasNext()) {
String word = it.next();
if (word.length() <= 2) {
it.remove(); // Remove short words
}
}

System.out.println("After removing short words: " + words);
}
}

Summary

AspectDetails
PurposeSafe iteration and modification of collections
Key MethodshasNext(), next(), remove()
AdvantagesSafe removal during iteration, universal interface
Best Use CasesWhen you need to remove elements while iterating
AlternativeEnhanced for loop (when not modifying collection)

Key Takeaways

  1. Always check hasNext() before calling next()
  2. Use iterator's remove() method for safe element removal
  3. Don't modify collection directly during iteration
  4. Create new iterators for each iteration cycle
  5. Handle exceptions appropriately

These notes cover the essential concepts and practical usage of Java Iterators based on W3Schools documentation and Java best practices.