Iterating over a composite

Viewed 128

In the Head First Design Patterns book, the authors describe using an iterator to traverse over composite data structures. They provide some sample code which, when executed, prints out a series of menu items stored within the composite. However, if you try to call the iterator more than once, it no longer works as expected and won't produce any results. The following code appears to be causing the problem:

public Iterator<MenuComponent> createIterator() {
    if (iterator == null) {
        iterator = new CompositeIterator(menuComponents.iterator());
    }
    return iterator;
}

In essence, they are creating a singleton iterator that cannot be reset for future iterations. Unfortunately, simply replacing this logic to return a new instance of the CompositeIterator also breaks the algorithm. An issue was raised on GitHub several years ago, although is yet to be resolved. Does anyone have any suggestions on how to overcome this issue?

1 Answers

As the linked issue says in the comments:

return iterator; // the `iterator' never resets to null once it's set.

We need to reset the iterator we are done with it, but not when the iterator still has elements left, because CompositeIterator depends on that.

One way to do this is to add another condition on which iterator is reset - when the iterator has no more elements:

public Iterator<MenuComponent> createIterator() {
    if (iterator == null || !iterator.hasNext()) {
        iterator = new CompositeIterator(menuComponents.iterator());
    }
    return iterator;
}
Related