# Class IteratorChain<E>

java.lang.Object
org.apache.commons.collections4.iterators.IteratorChain<E>

Type Parameters:
  `E` - the type of elements in this iterator.

All Implemented Interfaces:
  `Iterator<E>`

public class IteratorChain<E> extends Object implements Iterator<E>
An IteratorChain is an Iterator that wraps a number of Iterators.

This class makes multiple iterators look like one to the caller. When any method from the Iterator interface is called, the IteratorChain will delegate to a single underlying Iterator. The IteratorChain will invoke the Iterators in sequence until all Iterators are exhausted.

Under many circumstances, linking Iterators together in this manner is more efficient (and convenient) than reading out the contents of each Iterator into a List and creating a new Iterator.

Calling a method that adds new Iterator after a method in the Iterator interface has been called will result in an UnsupportedOperationException.

NOTE: As from version 3.0, the IteratorChain may contain no iterators. In this case the class will function as an empty iterator.

NOTE: As from version 4.0, the IteratorChain stores the iterators in a queue and removes any reference to them as soon as they are not used anymore. Thus, the methods `setIterator(Iterator)` and `getIterators()` have been removed and `size()` will return the number of remaining iterators in the queue.

Since:
  2.1

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `IteratorChain()`
  Constructs an IteratorChain with no Iterators.
  `IteratorChain(Collection<? extends Iterator<? extends E>> iteratorQueue)`
  Constructs a new `IteratorChain` over the collection of iterators.
  `IteratorChain(Iterator<? extends E> iterator)`
  Constructs an IteratorChain with a single Iterator.
  `IteratorChain(Iterator<? extends E>... iteratorQueue)`
  Constructs a new `IteratorChain` over the array of iterators.
  `IteratorChain(Iterator<? extends E> first, Iterator<? extends E> second)`
  Constructs a new `IteratorChain` over the two given iterators.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addIterator(Iterator<? extends E> iterator)`
  Add an Iterator to the end of the chain
  `boolean`
  `hasNext()`
  Return true if any Iterator in the IteratorChain has a remaining element.
  `boolean`
  `isLocked()`
  Determine if modifications can still be made to the IteratorChain.
  `E`
  `next()`
  Returns the next Object of the current Iterator
  `void`
  `remove()`
  Removes from the underlying collection the last element returned by the Iterator.
  `int`
  `size()`
  Returns the remaining number of Iterators in the current IteratorChain.
  `protected void`
  `updateCurrentIterator()`
  Updates the current iterator field to ensure that the current Iterator is not exhausted

  ### 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`

- ## Constructor Details

  - ### IteratorChain

    public IteratorChain()
    Constructs an IteratorChain with no Iterators.

    You will normally use `addIterator(Iterator)` to add some iterators after using this constructor.

  - ### IteratorChain

    public IteratorChain(Collection<? extends Iterator<? extends E>> iteratorQueue)
    Constructs a new `IteratorChain` over the collection of iterators.

    This method takes a collection of iterators. The newly constructed iterator will iterate through each one of the input iterators in turn.

    Parameters:
      `iteratorQueue` - the collection of iterators, not null
    Throws:
      `NullPointerException` - if iterators collection is or contains null
      `ClassCastException` - if iterators collection doesn't contain an iterator

  - ### IteratorChain

    public IteratorChain(Iterator<? extends E> iterator)
    Constructs an IteratorChain with a single Iterator.

    This method takes one iterator. The newly constructed iterator will iterate through that iterator. Thus calling this constructor on its own will have no effect other than decorating the input iterator.

    You will normally use `addIterator(Iterator)` to add some more iterators after using this constructor.

    Parameters:
      `iterator` - the first child iterator in the IteratorChain, not null
    Throws:
      `NullPointerException` - if the iterator is null

  - ### IteratorChain

    public IteratorChain(Iterator<? extends E>... iteratorQueue)
    Constructs a new `IteratorChain` over the array of iterators.

    This method takes an array of iterators. The newly constructed iterator will iterate through each one of the input iterators in turn.

    Parameters:
      `iteratorQueue` - the array of iterators, not null
    Throws:
      `NullPointerException` - if iterators array is or contains null

  - ### IteratorChain

    public IteratorChain(Iterator<? extends E> first, Iterator<? extends E> second)
    Constructs a new `IteratorChain` over the two given iterators.

    This method takes two iterators. The newly constructed iterator will iterate through each one of the input iterators in turn.

    Parameters:
      `first` - the first child iterator in the IteratorChain, not null
      `second` - the second child iterator in the IteratorChain, not null
    Throws:
      `NullPointerException` - if either iterator is null

- ## Method Details

  - ### addIterator

    public void addIterator(Iterator<? extends E> iterator)
    Add an Iterator to the end of the chain
    Parameters:
      `iterator` - Iterator to add
    Throws:
      `IllegalStateException` - if I've already started iterating
      `NullPointerException` - if the iterator is null

  - ### hasNext

    public boolean hasNext()
    Return true if any Iterator in the IteratorChain has a remaining element.
    Specified by:
      `hasNext` in interface `Iterator<E>`
    Returns:
      true if elements remain

  - ### isLocked

    public boolean isLocked()
    Determine if modifications can still be made to the IteratorChain. IteratorChains cannot be modified once they have executed a method from the Iterator interface.
    Returns:
      true if IteratorChain cannot be modified, false if it can

  - ### next

    public E next()
    Returns the next Object of the current Iterator
    Specified by:
      `next` in interface `Iterator<E>`
    Returns:
      Object from the current Iterator
    Throws:
      `NoSuchElementException` - if all the Iterators are exhausted

  - ### remove

    public void remove()
    Removes from the underlying collection the last element returned by the Iterator. As with next() and hasNext(), this method calls remove() on the underlying Iterator. Therefore, this method may throw an UnsupportedOperationException if the underlying Iterator does not support this method.
    Specified by:
      `remove` in interface `Iterator<E>`
    Throws:
      `UnsupportedOperationException` - if the remove operator is not supported by the underlying Iterator
      `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.

  - ### size

    public int size()
    Returns the remaining number of Iterators in the current IteratorChain.
    Returns:
      Iterator count

  - ### updateCurrentIterator

    protected void updateCurrentIterator()
    Updates the current iterator field to ensure that the current Iterator is not exhausted