gov.sandia.cognition.collection.MultiIterator Maven / Gradle / Ivy
/*
* File: MultiIterator.java
* Authors: Justin Basilico
* Company: Sandia National Laboratories
* Project: Cognitive Framework Lite
*
* Copyright March 24, 2006, Sandia Corporation. Under the terms of Contract
* DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
* or on behalf of the U.S. Government. Export of this program may require a
* license from the United States Government. See CopyrightHistory.txt for
* complete details.
*
*/
package gov.sandia.cognition.collection;
import gov.sandia.cognition.annotation.CodeReview;
import gov.sandia.cognition.annotation.CodeReviewResponse;
import gov.sandia.cognition.annotation.CodeReviews;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.NoSuchElementException;
/**
* The {@code MultiIterator} class implements an iterator that iterates over a
* bunch of internal iterators, exhausting one before moving to the next.
*
* @param The type for an entry in the collection.
* @author Justin Basilico
* @since 1.0
*/
@CodeReviews(
reviews={
@CodeReview(
reviewer="Kevin R. Dixon",
date="2008-02-08",
changesNeeded=false,
comments="Interface looks fine."
),
@CodeReview(
reviewer="Kevin R. Dixon",
date="2006-07-18",
changesNeeded=true,
comments="Non-standard use of direct-member access, instead of getters and setters. Please review.",
response=@CodeReviewResponse(
respondent="Justin Basilico",
date="2006-08-17",
moreChangesNeeded=false,
comments="Updated comments to indicate that it does not use getters"
)
)
}
)
public class MultiIterator
extends Object
implements Iterator,
Serializable
{
// Note: This class does not make use of the getters pattern because it
// is expected to be high-performance and instead uses direct access to
// the member variables.
/** The current iterator. */
private Iterator currentIterator;
/** The iterators themselves. */
private LinkedList> remainingIterators;
/**
* Creates a new instance of {@code MultiIterator}.
*
* @param iterables The collection of iterables to iterate using.
*/
public MultiIterator(
Collection extends Iterable> iterables )
{
super();
// Create the list of iterators.
LinkedList> iterators =
new LinkedList>();
for (Iterable iterable : iterables)
{
iterators.add( iterable.iterator() );
}
// Set the first iterator.
Iterator iterator = null;
if (!iterators.isEmpty())
{
iterator = iterators.removeFirst();
}
this.setCurrentIterator( iterator );
this.setRemainingIterators( iterators );
// Initialize the iterator by finding the first valid one.
this.findNextValidIterator();
}
/**
* {@inheritDoc}
*
* @return {@inheritDoc}
*/
public boolean hasNext()
{
// We have a next value if the current iterator is not null.
return this.currentIterator != null;
}
/**
* {@inheritDoc}
*
* @return {@inheritDoc}
*/
public EntryType next()
{
if (currentIterator == null)
{
throw new NoSuchElementException();
}
EntryType result = this.currentIterator.next();
this.findNextValidIterator();
return result;
}
/**
* {@inheritDoc}
*/
public void remove()
{
throw new UnsupportedOperationException();
}
/**
* Moves the iterator forward, attempting to find the next valid one.
*/
private void findNextValidIterator()
{
// Loop until either we find an iterator that has a next value or
// there are no more iterators.
while (this.currentIterator != null && !this.currentIterator.hasNext())
{
if (this.remainingIterators.isEmpty())
{
// No more iterators, so just set it to null. This will
// break the loop.
this.setCurrentIterator( null );
}
else
{
// Try using the next iterator as the current one.
this.setCurrentIterator( this.remainingIterators.removeFirst() );
}
}
}
/**
* Set the current iterators
*
* @param currentIterator The new current iterator.
*/
private void setCurrentIterator(
Iterator currentIterator )
{
this.currentIterator = currentIterator;
}
/**
* Sets the remaining iterators.
*
* @param remainingIterators The new remaining iterators.
*/
private void setRemainingIterators(
LinkedList> remainingIterators )
{
if (remainingIterators == null)
{
// Error: Bad parameter.
throw new NullPointerException(
"The remainingIterators cannot be null." );
}
this.remainingIterators = remainingIterators;
}
}