TechnologyZer
technologyzer.com

Exploring Iterator Design Pattern: A Comprehensive Guide

Understanding the Iterator Design Pattern

Iterator design pattern is a behavioral pattern that provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation. It separates the responsibility of accessing elements from the collection, making the collection easier to change without affecting the client code. The pattern consists of two main components: Iterator, Aggregate

Why Do We Need the Iterator Pattern?

Imagine you have a collection of objects, such as an array or a linked list. Typically, to access each element of the collection, you would use a loop like a for or while loop. However, this approach tightly couples the iteration logic with the collection implementation, making it difficult to change the collection structure or traversal method without modifying the iteration code.

Here’s where the Iterator pattern comes into play. It decouples the client code (the code that needs to iterate over the collection) from the collection implementation, providing a uniform interface for traversing different types of collections.

How Does the Iterator Pattern Work?

At the heart of the Iterator pattern lies two main components: the Iterator interface and the Aggregate interface.

  1. Iterator Interface: This interface defines methods for traversing the collection, such as next(), hasNext(), remove(), etc. Each concrete iterator class implements this interface to provide specific iteration behavior tailored to a particular collection.
  2. Aggregate Interface: This interface represents the collection of objects and typically includes a method that returns an iterator for traversing the collection. Each concrete collection class implements this interface and provides its own implementation of the iterator creation method.

Java Collection Framework uses Iterator Design Pattern.

Sample Code of Iterator Design Pattern

// Define the aggregate interface
interface Aggregate {
    Iterator createIterator();
}

// Concrete aggregate class
class ConcreteAggregate implements Aggregate {
    private List<String> items = new ArrayList<>();

    // Method to add items to the aggregate
    public void addItem(String item) {
        items.add(item);
    }

    // Method to get the iterator for the aggregate
    @Override
    public Iterator createIterator() {
        return new ConcreteIterator(items);
    }
}

// Define the iterator interface
interface Iterator {
    boolean hasNext();
    Object next();
}

// Concrete iterator class
class ConcreteIterator implements Iterator {
    private List<String> items;
    private int position = 0;

    public ConcreteIterator(List<String> items) {
        this.items = items;
    }

    // Method to check if there are more elements to iterate
    @Override
    public boolean hasNext() {
        return position < items.size();
    }

    // Method to retrieve the next element
    @Override
    public Object next() {
        if (hasNext()) {
            return items.get(position++);
        }
        return null;
    }
}

// Client code
public class IteratorExample {
    public static void main(String[] args) {
        ConcreteAggregate aggregate = new ConcreteAggregate();
        aggregate.addItem("Item 1");
        aggregate.addItem("Item 2");
        aggregate.addItem("Item 3");

        // Get the iterator for the aggregate
        Iterator iterator = aggregate.createIterator();

        // Iterate over the elements using the iterator
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

Leave a Comment