Class ObjectGraphIterator<E>

  • All Implemented Interfaces:
    java.util.Iterator<E>

    public class ObjectGraphIterator<E>
    extends java.lang.Object
    implements java.util.Iterator<E>
    An Iterator that can traverse multiple iterators down an object graph.

    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.

    Since:
    3.1
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private java.util.Iterator<? extends E> currentIterator
      The current iterator
      private E currentValue
      The current value
      private boolean hasNext
      Whether there is another element in the iteration
      private java.util.Iterator<? extends E> lastUsedIterator
      The last used iterator, needed for remove()
      private E root
      The root object in the tree
      private java.util.Deque<java.util.Iterator<? extends E>> stack
      The stack of iterators
      private Transformer<? super E,​? extends E> transformer
      The transformer to use
    • Constructor Summary

      Constructors 
      Constructor Description
      ObjectGraphIterator​(E root, Transformer<? super E,​? extends E> transformer)
      Constructs an ObjectGraphIterator using a root object and transformer.
      ObjectGraphIterator​(java.util.Iterator<? extends E> rootIterator)
      Constructs a ObjectGraphIterator that will handle an iterator of iterators.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      protected void findNext​(E value)
      Finds the next object in the iteration given any start object.
      protected void findNextByIterator​(java.util.Iterator<? extends E> iterator)
      Finds the next object in the iteration given an iterator.
      boolean hasNext()
      Checks whether there are any more elements in the iteration to obtain.
      E next()
      Gets the next element of the iteration.
      void remove()
      Removes from the underlying collection the last element returned.
      protected void updateCurrentIterator()
      Loops around the iterators to find the next value to return.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • Methods inherited from interface java.util.Iterator

        forEachRemaining
    • Field Detail

      • stack

        private final java.util.Deque<java.util.Iterator<? extends E>> stack
        The stack of iterators
      • root

        private E root
        The root object in the tree
      • transformer

        private final Transformer<? super E,​? extends E> transformer
        The transformer to use
      • hasNext

        private boolean hasNext
        Whether there is another element in the iteration
      • currentIterator

        private java.util.Iterator<? extends E> currentIterator
        The current iterator
      • currentValue

        private E currentValue
        The current value
      • lastUsedIterator

        private java.util.Iterator<? extends E> lastUsedIterator
        The last used iterator, needed for remove()
    • Constructor Detail

      • ObjectGraphIterator

        public ObjectGraphIterator​(E root,
                                   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.

        Parameters:
        root - the root object, null will result in an empty iterator
        transformer - the transformer to use, null will use a no effect transformer
      • ObjectGraphIterator

        public ObjectGraphIterator​(java.util.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.

        Parameters:
        rootIterator - the root iterator, null will result in an empty iterator
    • Method Detail

      • updateCurrentIterator

        protected void updateCurrentIterator()
        Loops around the iterators to find the next value to return.
      • findNext

        protected void findNext​(E value)
        Finds the next object in the iteration given any start object.
        Parameters:
        value - the value to start from
      • findNextByIterator

        protected void findNextByIterator​(java.util.Iterator<? extends E> iterator)
        Finds the next object in the iteration given an iterator.
        Parameters:
        iterator - the iterator to start from
      • hasNext

        public boolean hasNext()
        Checks whether there are any more elements in the iteration to obtain.
        Specified by:
        hasNext in interface java.util.Iterator<E>
        Returns:
        true if elements remain in the iteration
      • next

        public E next()
        Gets the next element of the iteration.
        Specified by:
        next in interface java.util.Iterator<E>
        Returns:
        the next element from the iteration
        Throws:
        java.util.NoSuchElementException - if all the Iterators are exhausted
      • remove

        public void remove()
        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.

        Specified by:
        remove in interface java.util.Iterator<E>
        Throws:
        java.lang.UnsupportedOperationException - if the remove operator is not supported by the underlying Iterator
        java.lang.IllegalStateException - if the next method has not yet been called, or the remove method has already been called after the last call to the next method.