
org.clapper.util.misc.MultiIterator Maven / Gradle / Ivy
Show all versions of javautil Show documentation
package org.clapper.util.misc;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collection;
import java.util.Enumeration;
import java.util.NoSuchElementException;
/**
* The MultiIterator class provides a way to iterate over
* multiple Collection, Enumeration and Iterator
* objects at once. You instantiate a MultiIterator object and add
* one or more Collection, Enumeration or
* Iterator objects to it; when you use the iterator, it iterates
* over the contents of each contained composite object, one by one, in the
* order they were added to the MultiIterator. When the iterator
* reaches the end of one object's contents, it moves on to the next
* object, until no more composite objects are left.
*
* @see java.util.Iterator
* @see java.util.Enumeration
* @see java.util.Collection
*/
public class MultiIterator implements Iterator, Iterable
{
/*----------------------------------------------------------------------*\
Private Data Elements
\*----------------------------------------------------------------------*/
/**
* The underlying objects being iterated over, stored in a Collection
*/
private Collection> aggregation = new ArrayList>();
/**
* The iterator for the list of aggregation
*/
private Iterator> aggregationIterator = null;
/**
* The iterator for the current object
*/
private Iterator it = null;
/*----------------------------------------------------------------------*\
Constructor
\*----------------------------------------------------------------------*/
/**
* Allocate a new MultiIterator object.
*/
public MultiIterator()
{
// Nothing to do
}
/**
* Allocate a new MultiIterator object that will iterate, in
* turn, over the contents of each Collection in the supplied
* array.
*
* @param array The Collections over which to iterate
*
* @see #addCollection(Collection)
*/
public MultiIterator (Collection array[])
{
for (int i = 0; i < array.length; i++)
aggregation.add (array[i].iterator());
}
/**
* Allocate a new MultiIterator object that will iterate, in
* turn, over the contents of each Collection in the supplied
* Collection
*
* @param coll A Collection of Collection objects
*
* @see #addCollection(Collection)
*/
public MultiIterator (Collection> coll)
{
for (Iterator> iterator = coll.iterator();
iterator.hasNext(); )
{
aggregation.add (iterator.next().iterator());
}
}
/*----------------------------------------------------------------------*\
Public Methods
\*----------------------------------------------------------------------*/
/**
* Add a Collection to the end of the list of composite
* objects being iterated over. It's safe to call this method while
* iterating, as long as you haven't reached the end of the last
* composite object currently in the iterator.
*
* Note: This method is simply shorthand for:
*
*
* addIterator (collection.iterator());
*
*
* @param collection The Collection to add.
*
* @see #addIterator
* @see #addEnumeration
*/
public void addCollection (Collection collection)
{
aggregation.add (collection.iterator());
}
/**
* Add an Iterator to the end of the list of composite objects
* being iterated over. It's safe to call this method while iterating,
* as long as you haven't reached the end of the last composite object
* currently in the iterator.
*
* @param iterator The Iterator to add.
*
* @see #addCollection
* @see #addEnumeration
*/
public void addIterator (Iterator iterator)
{
aggregation.add (iterator);
}
/**
* Add an Enumeration to the end of the list of composite
* objects being iterated over. It's safe to call this method while
* iterating, as long as you haven't reached the end of the last
* composite object currently in the iterator.
*
* Note: This method is simply shorthand for:
*
* * {@code
* addIterator (new EnumerationIterator (enumeration));
* }
*
*
* @param enumeration The Enumeration to add.
*
* @see #addCollection
* @see #addIterator
* @see EnumerationIterator
*/
public void addEnumeration (Enumeration enumeration)
{
aggregation.add (new EnumerationIterator (enumeration));
}
/**
* Determine whether the underlying Iterator has more
* elements.
*
* @return true if and only if a call to
* nextElement() will return an element,
* false otherwise.
*
* @see #next
*/
public boolean hasNext()
{
boolean someLeft = false;
checkIterator();
if (it != null)
someLeft = it.hasNext();
return someLeft;
}
/**
* Returns this iterator. Necessary for the Iterable interface.
*
* @return this object
*/
public Iterator iterator()
{
return this;
}
/**
* Get the next element from the underlying array.
*
* @return the next element from the underlying array
*
* @throws NoSuchElementException No more elements exist
*
* @see java.util.Iterator#next
*/
public T next() throws NoSuchElementException
{
T result = null;
checkIterator();
if (it != null)
result = it.next();
return result;
}
/**
* Remove the object most recently extracted from the iterator.
* The object is removed from whatever underlying Collection
* is currently being traversed.
*/
public void remove()
{
if (it != null)
it.remove();
}
/*----------------------------------------------------------------------*\
Private Methods
\*----------------------------------------------------------------------*/
private synchronized void checkIterator()
{
if (aggregationIterator == null)
{
it = null;
aggregationIterator = aggregation.iterator();
if (aggregationIterator.hasNext())
it = aggregationIterator.next();
}
while ( (it != null) && (! it.hasNext()) )
{
if (! aggregationIterator.hasNext())
it = null;
else
it = aggregationIterator.next();
}
}
}