This iterator can extract multiple objects from a complex tree-like object graph.
The iteration starts from a single root object.
It uses a Transformer to extract the iterators and elements.
Its main benefit is that no intermediate List is created.
For example, consider an object graph:
|- Branch -- Leaf
| \- Leaf
|- Tree | /- Leaf
| |- Branch -- Leaf
Forest | \- Leaf
| |- Branch -- Leaf
| | \- Leaf
|- Tree | /- Leaf
|- Branch -- Leaf
|- Branch -- Leaf
The following Transformer, used in this class, will extract all
the Leaf objects without creating a combined intermediate list:
public Object transform(Object input) {
if (input instanceof Forest) {
return ((Forest) input).treeIterator();
}
if (input instanceof Tree) {
return ((Tree) input).branchIterator();
}
if (input instanceof Branch) {
return ((Branch) input).leafIterator();
}
if (input instanceof Leaf) {
return input;
}
throw new ClassCastException();
}
Internally, iteration starts from the root object. When next is called, the transformer is called to examine the object. The transformer will return either an iterator or an object. If the object is an Iterator, the next element from that iterator is obtained and the process repeats. If the element is an object it is returned.
Under many circumstances, linking Iterators together in this manner is more efficient (and convenient) than using nested for loops to extract a list.
| Modifier and Type | Field and Description |
|---|---|
| private Iterator | currentIterator
The current iterator |
| private E | currentValue
The current value |
| private boolean | hasNext
Whether there is another element in the iteration |
| private Iterator | lastUsedIterator
The last used iterator, needed for remove() |
| private E | root
The root object in the tree |
| private final Deque | stack
The stack of iterators |
| private final Transformer | transformer
The transformer to use |
| Access | Constructor and Description |
|---|---|
| public | ObjectGraphIterator(final E
the root object, null will result in an empty iterator root, final Transformer<? super E, ? extends E> the transformer to use, null will use a no effect transformer transformer)Constructs an ObjectGraphIterator using a root object and transformer. |
| public | ObjectGraphIterator(final Iterator<? extends E>
the root iterator, null will result in an empty iterator rootIterator)Constructs a ObjectGraphIterator that will handle an iterator of iterators. |
| Modifier and Type | Method and Description |
|---|---|
| protected void | findNext(final E
the value to start from value)Finds the next object in the iteration given any start object. |
| protected void | findNextByIterator(final Iterator<? extends E>
the iterator to start from iterator)Finds the next object in the iteration given an iterator. |
| public boolean | Returns: true if elements remain in the iterationImplements java. |
| public E | Returns: the next element from the iterationImplements java. |
| public void | remove()
Overrides default java. |
| protected void |
| currentIterator | back to summary |
|---|---|
| private Iterator<? extends E> currentIterator The current iterator | |
| currentValue | back to summary |
|---|---|
| private E currentValue The current value | |
| hasNext | back to summary |
|---|---|
| private boolean hasNext Whether there is another element in the iteration | |
| lastUsedIterator | back to summary |
|---|---|
| private Iterator<? extends E> lastUsedIterator The last used iterator, needed for remove() | |
| root | back to summary |
|---|---|
| private E root The root object in the tree | |
| stack | back to summary |
|---|---|
| private final Deque<Iterator<? extends E>> stack The stack of iterators | |
| transformer | back to summary |
|---|---|
| private final Transformer<? super E, ? extends E> transformer The transformer to use | |
| ObjectGraphIterator | back to summary |
|---|---|
| public ObjectGraphIterator(final E root, final Transformer<? super E, ? extends E> transformer) Constructs an ObjectGraphIterator using a root object and transformer. The root object can be an iterator, in which case it will be immediately looped around.
| |
| ObjectGraphIterator | back to summary |
|---|---|
| public ObjectGraphIterator(final Iterator<? extends E> rootIterator) Constructs a ObjectGraphIterator that will handle an iterator of iterators. This constructor exists for convenience to emphasise that this class can be used to iterate over nested iterators. That is to say that the iterator passed in here contains other iterators, which may in turn contain further iterators.
| |
| findNext | back to summary |
|---|---|
| protected void findNext(final E value) Finds the next object in the iteration given any start object.
| |
| findNextByIterator | back to summary |
|---|---|
| protected void findNextByIterator(final Iterator<? extends E> iterator) Finds the next object in the iteration given an iterator.
| |
| hasNext | back to summary |
|---|---|
| public boolean hasNext() Implements java. Checks whether there are any more elements in the iteration to obtain.
| |
| next | back to summary |
|---|---|
| public E next() Implements java. Gets the next element of the iteration.
| |
| remove | back to summary |
|---|---|
| public void remove() Overrides default java. Removes from the underlying collection the last element returned. This method calls remove() on the underlying Iterator and it may throw an UnsupportedOperationException if the underlying Iterator does not support this method.
| |
| updateCurrentIterator | back to summary |
|---|---|
| protected void updateCurrentIterator() Loops around the iterators to find the next value to return. | |