package org.vertexium.util;
import com.google.common.collect.Iterables;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
public class JoinIterable<T> implements Iterable<T> {
private final Iterable<? extends T>[] iterables;
public JoinIterable(Iterable<? extends Iterable<? extends T>> iterables) {
//noinspection unchecked
this(Iterables.toArray(iterables, Iterable.class));
}
@SafeVarargs
public JoinIterable(Iterable<? extends T>... iterables) {
this.iterables = iterables;
}
@Override
public Iterator<T> iterator() {
if (this.iterables.length == 0) {
return new Iterator<T>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public T next() {
return null;
}
@Override
public void remove() {
}
};
}
final Queue<Iterable<? extends T>> iterables = new LinkedList<>();
Collections.addAll(iterables, this.iterables);
final IteratorWrapper it = new IteratorWrapper();
it.iterator = iterables.remove().iterator();
return new Iterator<T>() {
private T next;
private T current;
@Override
public boolean hasNext() {
loadNext();
return next != null;
}
@Override
public T next() {
loadNext();
if (this.next == null) {
throw new IllegalStateException("iterable doesn't have a next element");
}
this.current = this.next;
this.next = null;
return this.current;
}
@Override
public void remove() {
it.iterator.remove();
}
private void loadNext() {
if (this.next != null) {
return;
}
while (true) {
if (it.iterator.hasNext()) {
break;
}
if (iterables.size() == 0) {
this.next = null;
return;
}
it.iterator = iterables.remove().iterator();
}
this.next = it.iterator.next();
}
};
}
private class IteratorWrapper {
public Iterator<? extends T> iterator;
}
protected Iterable<? extends T>[] getIterables() {
return iterables;
}
}