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

org.codefilarete.tool.collection.PairIterator Maven / Gradle / Ivy

package org.codefilarete.tool.collection;

import java.util.Iterator;
import java.util.NoSuchElementException;

import org.codefilarete.tool.Duo;

/**
 * {@link Iterator} of 2 others by giving {@link Duo}s. Gives elements while 2 Iterators have elements together.
 * 
 * @param  type of first {@link Iterator}'s element
 * @param  type of second {@link Iterator}'s element
 * @author Guillaume Mary
 */
public class PairIterator implements Iterator> {
	
	protected Iterator iterator1;
	protected Iterator iterator2;
	
	public PairIterator(Iterable iterator1, Iterable iterator2) {
		this(iterator1.iterator(), iterator2.iterator());
	}
	
	public PairIterator(Iterator iterator1, Iterator iterator2) {
		this.iterator1 = iterator1;
		this.iterator2 = iterator2;
	}
	
	@Override
	public boolean hasNext() {
		return iterator1.hasNext() && iterator2.hasNext();
	}
	
	@Override
	public Duo next() {
		return new Duo<>(iterator1.next(), iterator2.next());
	}
	
	@Override
	public void remove() {
		iterator1.remove();
		iterator2.remove();
	}
	
	/**
	 * {@link Iterator} which continues while one of the surrogate {@link Iterator} still has elements. So it stops when both {@link Iterator}s are
	 * drained.
	 * Gives the pair as a {@link Duo}.
	 * Missing values are overridable through {@link #getMissingKey()} and {@link #getMissingValue()}.
	 *
	 * @param  type of first {@link Iterator}'s element
	 * @param  type of second {@link Iterator}'s element
	 */
	public static class UntilBothIterator extends PairIterator {
		
		public UntilBothIterator(Iterable iterator1, Iterable iterator2) {
			super(iterator1, iterator2);
		}
		
		public UntilBothIterator(Iterator iterator1, Iterator iterator2) {
			super(iterator1, iterator2);
		}
		
		@Override
		public boolean hasNext() {
			return iterator1.hasNext() || iterator2.hasNext();
		}
		
		@Override
		public Duo next() {
			K val1;
			if (iterator1.hasNext()) {
				val1 = iterator1.next();
			} else {
				val1 = getMissingKey();
			}
			V val2;
			if (iterator2.hasNext()) {
				val2 = iterator2.next();
			} else {
				val2 = getMissingValue();
			}
			return new Duo<>(val1, val2);
		}
		
		public K getMissingKey() {
			return null;
		}
		
		public V getMissingValue() {
			return null;
		}
	}
	
	/**
	 * {@link Iterator} running indefinitely, starts by giving surrogate's elements, then gives what {@link #getMissingElement()} returns
	 * (default is null).
	 * 
	 * @param 
	 */
	public static class InfiniteIterator implements Iterator {
		
		private final Iterator delegate;
		
		public InfiniteIterator(Iterator delegate) {
			this.delegate = delegate;
		}
		
		@Override
		public boolean hasNext() {
			return true;
		}
		
		@Override
		public E next() {
			try {
				return delegate.next();
			} catch (NoSuchElementException e) {
				return getMissingElement();
			}
		}
		
		@Override
		public void remove() {
			delegate.remove();
		}
		
		public E getMissingElement() {
			return null;
		}
	}
	
	/**
	 * {@link Iterator} without any element. Stub for API that needs an {@link Iterator}.
	 * @param 
	 */
	public static class EmptyIterator implements Iterator {
		
		@Override
		public boolean hasNext() {
			return false;
		}
		
		@Override
		public E next() {
			throw new NoSuchElementException();
		}
		
		@Override
		public void remove() {
			
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy