Create a gist now

Instantly share code, notes, and snippets.

It implements an Iterable that take elements from a list of Iterable in a round robin fashion. The test is most explicative than the description.
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterators.cycle;
import static java.util.Arrays.asList;
import java.util.Iterator;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.UnmodifiableIterator;
public class RoundRobinIterable<T> implements Iterable<T> {
private final Iterable<Iterable<T>> iterables;
public RoundRobinIterable(Iterable<Iterable<T>> iterables) {
checkNotNull(iterables);
this.iterables = iterables;
}
@SafeVarargs
public static <T> RoundRobinIterable of(Iterable<T>... xs) {
return new RoundRobinIterable<>(asList(xs));
}
@Override
public Iterator<T> iterator() {
final Iterator<Iterator<T>> it = cycle(filter(
FluentIterable.from(iterables)
.transform(RoundRobinIterable.<T>iteratorFn())
.toList(),
hasNextPr()
));
return new UnmodifiableIterator<T>() {
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public T next() {
return it.next().next();
}
};
}
private enum HasNext implements Predicate<Iterator<?>> {
INSTANCE;
@Override
public boolean apply(Iterator<?> input) {
return input.hasNext();
}
}
private static Predicate<Iterator<?>> hasNextPr() {
return HasNext.INSTANCE;
}
private static <T> Function<Iterable<T>, Iterator<T>> iteratorFn() {
return new Function<Iterable<T>, Iterator<T>>() {
@Override
public Iterator<T> apply(Iterable<T> input) {
return input.iterator();
}
};
}
}
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Arrays.asList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import java.util.List;
import org.junit.Test;
/**
* @author Filippo De Luca - me@filippodeluca.com
*/
public class RoundRobinIterableTest extends AbstractUnitTest {
@Test
public void iteratorShouldBeWorkAsExpected() {
List<Integer> numbers = newArrayList(RoundRobinIterable.of(asList(1,2,3,9), asList(4,5), asList(6,7,8)));
List<Integer> expected = newArrayList(1, 4, 6, 2, 5, 7, 3, 8, 9);
assertThat(numbers, equalTo(expected));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment