Provide a way to access elements of an aggregate object sequentially without exposing its underlying representation.
// ─── EXAMPLE 1 ──────────────────────────────────────────────────────────────
// WHAT WE ARE IMPLEMENTING:
// A custom HR profiles directory enabling client traversal without exposing
// internal list implementations.
//
// WHERE THE ITERATOR FITS IN:
// ProfileIterator acts as the Iterator interface. ProfileCollection acts as
// the Aggregate collection exposing .createIterator().
// ────────────────────────────────────────────────────────────────────────────
import java.util.ArrayList;
import java.util.List;
interface Iterator<T> {
boolean hasNext();
T next();
}
// --- Custom collection ---
class BrowseHistory {
private final List<String> urls = new ArrayList<>();
public void push(String url) { urls.add(url); }
public Iterator<String> createIterator() {
return new ListIterator(urls);
}
// --- Concrete iterator ---
private static class ListIterator implements Iterator<String> {
private final List<String> urls;
private int index = 0;
ListIterator(List<String> urls) { this.urls = urls; }
public boolean hasNext() { return index < urls.size(); }
public String next() {
if (!hasNext()) throw new java.util.NoSuchElementException();
return urls.get(index++);
}
}
}
// --- Client ---
public class Main {
public static void main(String[] args) {
BrowseHistory history = new BrowseHistory();
history.push("google.com");
history.push("github.com");
history.push("stackoverflow.com");
Iterator<String> it = history.createIterator();
while (it.hasNext()) {
System.out.println(" " + it.next());
}
}
}