Problem: Given an iterator of iterators, can you give me back an iterator which flattens the given iterator. Ex : Suppose you are given an iterator which has these objects - "1", "2", "3", , , then the flattened iterator returned by you should have "1", "2", "3", "4", "5", "6", "7", "8", "9". Iterators may be nested to any level.
This problem can be solved by implementing a FlattenIterator which takes in the given iterator as an agrument in the constructor and delegating the hasNext() and next() calls to the given iterator using a stack. The given iterator is pushed on to the stack. Nested iterators are pushed on to the stack before traversing and once there are no more elements in the iterator, it is popped from the stack. Here is the code -
This problem can be solved by implementing a FlattenIterator which takes in the given iterator as an agrument in the constructor and delegating the hasNext() and next() calls to the given iterator using a stack. The given iterator is pushed on to the stack. Nested iterators are pushed on to the stack before traversing and once there are no more elements in the iterator, it is popped from the stack. Here is the code -
import java.util.*;
/**
* User: blogkoder
* Date: Jul 28, 2008
* Time: 9:32:39 PM
*/
public class FlattenIterator implements Iterator
{
private final Stack<Iterator<?>> iterators = new Stack<Iterator<?>>();
private boolean hasNextCalled;
private boolean hasNextValue;
private Object next;
/**
* Default constructor which takes in an iterator.
* @param iterator
* @throws RuntimeException - if iterator is null.
*/
public FlattenIterator(Iterator iterator)
{
if (iterator == null)
{
throw new RuntimeException("Iterator cannot be null.");
}
iterators.push(iterator);
}
public boolean hasNext()
{
boolean hasNext = false;
if (hasNextCalled)
{
hasNext = hasNextValue;
}
else
{
iterateNext();
hasNextCalled = true;
hasNext = (next != null);
hasNextValue = hasNext;
}
return hasNext;
}
private void iterateNext()
{
if (!iterators.empty())
{
if (iterators.peek().hasNext())
{
next = iterators.peek().next();
if (next instanceof Iterator)
{
iterators.push((Iterator) next);
iterateNext();
}
}
else
{
iterators.pop();
iterateNext();
}
}
else
{
next = null;
}
}
public Object next()
{
Object returnValue = null;
if (hasNextCalled)
{
hasNextCalled = false;
returnValue = next;
}
else
{
iterateNext();
returnValue = next;
}
if (returnValue == null)
{
throw new NoSuchElementException();
}
return returnValue;
}
public void remove()
{
}
}
Comments