Hierarchical Iterator
import static com.google.common.collect.ImmutableList.of;
import java.util.Iterator;
import java.util.LinkedList;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.Lists;
/**
* This Iterator could be used for hierarchical data structure (e.g. Trees).
*
* @author Andreas Höhmann
* @param <T>
*/
public abstract class AbstractHierarchialIterator<T> extends AbstractIterator<T> {
private final LinkedList<Iterable<T>> stack = Lists.newLinkedList();
private Iterator<T> current;
public AbstractHierarchialIterator(final T start) {
this(of(start));
}
private AbstractHierarchialIterator(final Iterable<T> start) {
current = start.iterator();
}
/**
* An concrete hierarchical iterator has to implement a method to
* visit the children of an element.
*
* @param currentElement
* @return never <code>null</code>
*/
protected abstract Iterable<T> childrenOf(T currentElement);
@Override
protected T computeNext() {
while (true) {
if (current.hasNext()) {
final T next = current.next();
stack.add(childrenOf(next));
return next;
}
if (stack.isEmpty()) {
break;
}
current = stack.removeFirst().iterator();
}
return endOfData();
}
}
Examples
AbstractHierarchialIterator<Foobar> i =
new AbstractHierarchialIterator<Foobar>(foobarStart) {
@Override
protected Iterable<Foobar> childrenOf(final Foobar currentElement) {
// <--- here you have to implement something
return currentElement.getFoobarChildren();
}
};
// example 1 - show all foobars
while (i.hasNext()) {
System.out.println(i.next());
}
// example 2 - search the first "foo"
Foobar foo = com.google.common.collect.Iterators.find(i, new Predicate<Foobar>() {
@Override
public boolean apply(final Foobar input) {
return "foo".equals(input.getName());
}
}, null);
Advertisement
Categories: Guava, Java, Softwareentwicklung
guava, hierarchical, iterator
Some questions.
a) The variable “stack” is a LinkedList, why not a real “Stack”?
b) In which order will the children be processed? In-, pre- or post-order? It is not configurable nor documented
Greetings, Ben
Hi Ben,
a) what class do you mean? Vector?
… you are right … a next step could be the usage of the strategy pattern, in combination with the builder pattern it would be quite easy to support all aspects of traversing a hierarchical data-structure.
b) this iterator will do it with http://en.wikipedia.org/wiki/Breadth-first_search, this simple code doesn’t need any documentation
cya
höhmi