All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.darkmist.alib.collection.Iterators Maven / Gradle / Ivy

The newest version!
/*
 *  Copyright (C) 2012 Ed Schaller 
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package net.darkmist.alib.collection;

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.NoSuchElementException;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Iterators
{
	private static final Class CLASS = Iterators.class;
	@SuppressWarnings("unused")
	private static final Logger logger = LoggerFactory.getLogger(CLASS);

	/**
	 * Package private so deprecated IteratorUtil can subclass...
	 */
	Iterators()
	{
	}

	public static  Set addToSet(Set set, Iterator i)
	{
		while(i.hasNext())
		{
			T e = i.next();
			set.add(e);
		}
		return set;
	}

	public static  LinkedHashSet toLinkedHashSet(Iterator i)
	{
		LinkedHashSet set = new LinkedHashSet();
		addToSet(set, i);
		return set;
	}
	
	public static  LinkedHashSet toLinkedHashSet(Iterator i, int sizeGuess)
	{
		LinkedHashSet set = new LinkedHashSet(sizeGuess);
		addToSet(set, i);
		return set;
	}

	public static  Set toSet(Iterator i)
	{
		Set set = new HashSet();
		addToSet(set, i);
		return set;
	}

	public static  Set toSet(Iterator i, int sizeGuess)
	{
		Set set = new HashSet(sizeGuess);
		addToSet(set, i);
		return set;
	}

	@SuppressWarnings("unchecked")
	public static  T[] toSetArray(Iterator i)
	{
		return (T[])toLinkedHashSet(i).toArray();
	}

	@SuppressWarnings("unchecked")
	public static  T[] toSetArray(Iterator i, int sizeGuess)
	{
		return (T[])toLinkedHashSet(i, sizeGuess).toArray();
	}

	/**
	 * Empty iterator singleton.
	 */
	private static final class EmptyIterator extends NonRemovingIterator
	{
		@SuppressWarnings("rawtypes")
		private static EmptyIterator SINGLETON = new EmptyIterator();

		private EmptyIterator()
		{
		}

		@SuppressWarnings("unchecked")
		static  EmptyIterator instance()
		{
			return SINGLETON;
		}

		@Override
		public boolean hasNext()
		{
			return false;
		}

		@Override
		public T next()
		{
			throw new NoSuchElementException("This iterator has no content!");
		}

		/**
		 * Standard equals. This allows comparision of this
		 * iterator with a non-EmptyIterator Iterator. They are
		 * considered equal if the other iterators {@link
		 * #hasNext()} also returns false.
		 * @param o Object to compare with
		 * @return true if o is an iterator and o.hasNext()
		 * 	is false.
		 */
		@Override
		public boolean equals(Object o)
		{
			if(o == null)
				return false;
			if(!(o instanceof Iterator))
				return false;
			return !((Iterator)o).hasNext();
		}
		
		/**
		 *  Always returns zero.
		 */
		@Override
		public int hashCode()
		{
				return 0;
		}
	}

	/**
	 * Get an empty iterator.
	 * @return Iterator who's hasNext() is always false.
	 */
	public static  Iterator getEmptyIterator()
	{
		return EmptyIterator.instance();
	}

	/**
	 * Iterator that iterates over an array. Note that this does
	 * NOT make a copy of the array so changes to the passed array
	 * may cause issues with iteration.
	 */
	static class ArrayIterator extends NonRemovingIterator
	{
		private T[] array;
		private int i;

		/**
		 * Given an array, create an iterator.
		 * @param array The array to iterate over.
		 * @throws NullPointerException if array is null.
		 */
		public ArrayIterator(T...array)
		{
			if(array == null)
				throw new NullPointerException("Array was null");
			this.array = array;
			this.i = 0;
		}
	
		@Override
		public boolean hasNext()
		{
			return (i Iterator getArrayIterator(T...array)
	{
		if(array == null || array.length == 0)
			return getEmptyIterator();
		return new ArrayIterator(array);
	}
	
	static class IteratorEnumeration implements Enumeration
	{
		private Iterator i;

		IteratorEnumeration(Iterator i)
		{
			this.i = i;
		}

		@Override
		public final boolean hasMoreElements()
		{
			return i.hasNext();
		}

		@Override
		public final E nextElement()
		{
			return i.next();
		}
	}

	public static  Enumeration asEnumeration(Iterator i)
	{
		if(i == null || !i.hasNext())
			return Enumerations.getEmptyEnumeration();
		return new IteratorEnumeration(i);
	}

	/** Iterator for a single item. Why? So items can be trivially added to a IteratorIterator. */
	static class SingleIterator extends NonRemovingIterator
	{
		private U single;
		private boolean done;	// so we can actually iterate a null value....

		public SingleIterator(U single)
		{
			this.single=single;
			done=false;
		}

		@Override
		public boolean hasNext()
		{
			return !done;
		}

		@Override
		public U next()
		{
			U ret;
	
			if(done)
				throw new NoSuchElementException("Single element already iterated over");
			ret = single;
			single = null;
			return ret;
		}
	}

	public static  Iterator getSingletonIterator(T singleton)
	{
		return new SingleIterator(singleton);
	}
}