PandaLib/pandalib-util/src/main/java/fr/pandacube/lib/util/IteratorIterator.java

109 lines
3.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package fr.pandacube.lib.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* An {@link Iterator} that iterate over all the elements of all the provided iterators.
* In other words, this class concatenate the provided iterators.
* @param <T> the type of the values in the iterators
*/
public class IteratorIterator<T> implements Iterator<T> {
/**
* Create an {@link IteratorIterator} with the provided {@link Collection} of {@link Iterable}.
* The iterables iterators will be concatenated in the order of the collections iterator.
* @param coll the collection of iterables.
* @return a new instance of {@link IteratorIterator} iterating over the elements of the provided iterables.
* @param <T> the type of the values in the iterables.
*/
public static <T> IteratorIterator<T> ofCollectionOfIterable(Collection<Iterable<T>> coll) {
return new IteratorIterator<>(coll.stream().map(Iterable::iterator).iterator());
}
/**
* Create an {@link IteratorIterator} with the provided {@link Collection} of {@link Iterator}.
* The iterators will be concatenated in the order of the collections iterator.
* @param coll the collection of iterators.
* @return a new instance of {@link IteratorIterator} iterating over the elements of the provided iterators.
* @param <T> the type of the values in the iterators.
*/
public static <T> IteratorIterator<T> ofCollectionOfIterator(Collection<Iterator<T>> coll) {
return new IteratorIterator<>(new ArrayList<>(coll).iterator());
}
/**
* Create an {@link IteratorIterator} with the provided array of {@link Iterable}.
* The iterables iterators will be concatenated in the order of the array.
* @param arr the array of iterables.
* @return a new instance of {@link IteratorIterator} iterating over the elements of the provided iterables.
* @param <T> the type of the values in the iterables.
*/
@SafeVarargs
public static <T> IteratorIterator<T> ofArrayOfIterable(Iterable<T>... arr) {
return new IteratorIterator<>(Arrays.stream(arr).map(Iterable::iterator).iterator());
}
/**
* Create an {@link IteratorIterator} with the provided array of {@link Iterator}.
* The iterators will be concatenated in the order of the array.
* @param arr the array of iterators.
* @return a new instance of {@link IteratorIterator} iterating over the elements of the provided iterators.
* @param <T> the type of the values in the iterators.
*/
@SafeVarargs
public static <T> IteratorIterator<T> ofArrayOfIterator(Iterator<T>... arr) {
return new IteratorIterator<>(Arrays.asList(arr).iterator());
}
private final Iterator<Iterator<T>> iterators;
private Iterator<T> currentValueIterator = null;
private Iterator<T> nextValueIterator = null;
private IteratorIterator(Iterator<Iterator<T>> iterators) {
this.iterators = iterators;
}
private void fixNextIterator() {
if (nextValueIterator != null && !nextValueIterator.hasNext()) {
nextValueIterator = null;
}
}
private void fixState() {
fixNextIterator();
while (nextValueIterator == null && iterators.hasNext()) {
nextValueIterator = iterators.next();
fixNextIterator();
}
}
@Override
public boolean hasNext() {
fixState();
return nextValueIterator != null && nextValueIterator.hasNext();
}
@Override
public T next() {
if (!hasNext())
throw new NoSuchElementException("No next value found in iterator.");
currentValueIterator = nextValueIterator;
return currentValueIterator.next();
}
@Override
public void remove() {
if (currentValueIterator == null)
throw new IllegalStateException();
currentValueIterator.remove();
}
}