package net.varkhan.base.containers;
import java.util.NoSuchElementException;
/**
* <b>An iterator over the objects in a content container.</b>
* <p/>
* This interface has been copied from {@link java.util.Iterator} (which it extends),
* for convenience in proximity of {@link Iterable}.
* <p/>
*
* @param <Type> the type of the objects in the container
*
* @see java.util.Iterator
* @see java.lang.Iterable#iterator()
*
* @author varkhan
* @date 1/1/11
* @time 3:50 AM
*/
public interface Iterator<Type> extends java.util.Iterator<Type> {
/**
* Indicates whether the iteration has more elements.
* <p/>
* (In other words, returns {@literal true} if {@link #next} would return an element
* rather than throwing an exception.)
*
* @return {@literal true} if the iterator has more elements
*/
public boolean hasNext();
/**
* Returns the next element in the iteration.
*
* @return the next element in the iteration
*
* @throws java.util.NoSuchElementException if the iteration has no more elements
*/
public Type next();
/**
*
* Removes from the underlying collection the last element returned by the iterator
* (optional operation).
* <p/>
* This method can be called only once per call to {@link #next}. The behavior of an
* iterator is unspecified if the underlying collection is modified while the iteration
* is in progress in any way other than by calling this method.
*
* @throws java.lang.UnsupportedOperationException if the operation is not supported by this Iterator
* @throws java.lang.IllegalStateException if the {@link #next} method has not yet been called, or the
* {@link #remove} method has already been called after the last call to the {@link #next} method
*/
public void remove();
/**********************************************************************************
** Static predefined iterators
**/
/**
* An empty iterator (whose {@code hasNext()} and {@code hasPrevious()}
* methods always return {@literal false}, and {@code next()} returns {@literal null}.
*/
public static final Iterator EMPTY=new Empty();
/**
* An empty iterator (whose {@code hasNext()} and {@code hasPrevious()}
* methods always return {@literal false}, and {@code next()} returns {@literal null}.
*/
public static final class Empty<Type> implements Iterator<Type> {
public boolean hasNext() { return false; }
public Type next() { return null; }
public void remove() { }
}
/**
* A singleton iterator, that returns a single element.
*/
public static final class Singleton<Type> implements Iterator<Type> {
private final Type element;
private volatile boolean available=true;
/**
* Create a singleton iterator.
*
* @param e the single element this iterator returns
*/
public Singleton(Type e) { element=e; }
public boolean hasNext() { return available; }
public Type next() {
if(!available) throw new NoSuchElementException();
available=false;
return element;
}
public boolean hasPrevious() { return !available; }
public void remove() { throw new UnsupportedOperationException(); }
}
/**
* An enumeration iterator, that returns all elements in an array, in order.
*/
public static final class Enumerate<Type> implements Iterator<Type> {
private final Type[] elements;
private volatile int pos = 0;
/**
* Create an enumeration iterator.
*
* @param e the array of all the elements to return
*/
public Enumerate(Type... e) { elements = e; }
public boolean hasNext() { return elements!=null&&pos<elements.length; }
public Type next() {
if(elements==null||pos>=elements.length) throw new NoSuchElementException();
return elements[pos++];
}
public void remove() { throw new UnsupportedOperationException(); }
}
/**
* A sequence iterator, that returns all the elements of a series of iterators, in order.
*/
public static final class Sequence<Type> implements Iterator<Type> {
private final Iterator<? extends Type>[] segments;
private volatile int pos = -1;
/**
* Create a sequence iterator.
*
* @param s the array of all the subsequence iterators
*/
public Sequence(Iterator<? extends Type>[] s) { segments = s; }
public boolean hasNext() {
int pos = this.pos;
if(pos<0) pos = 0;
while(pos<segments.length && !segments[pos].hasNext()) pos ++;
return pos<segments.length && segments[pos].hasNext();
}
public Type next() {
if(pos<0) pos = 0;
while(pos<segments.length && !segments[pos].hasNext()) pos ++;
if(pos>=segments.length) throw new NoSuchElementException();
return segments[pos].next();
}
public void remove() {
if(pos<0 || pos>=segments.length) throw new IllegalStateException();
segments[pos].remove();
}
}
}