Round-Robin Iterable

1 minute read

It is a solution I have written because my collegue was struggling to write a code that was collecting one element for each list in an ordered way and accepting list of different size.

The problem was collecting 50 images from a third party supplier. Each record has a set of albums, a ordered list of image, and a set of featured images pick from the albums. We want to collect 50 images, starting from the feature and then going trough the albums in a round-robin fashon (the first for each album, the second and so on). The album may have different size.

So if we have the feed containing these image id:

featuredImages: [1, 5, 4, 9]
albumOne: [1, 2, 3, 4]
albumTwo: [5, 6, 7, 8, 9, 10]
albumThree: [11]
albumFour: [12, 13, 14]

And we want to collect 10 images we got:

images: [1, 5, 4, 9, 5, 11, 12, 2, 6, 13]

The most simple solution I have think to to has been to use Guava Iterables to limit the image to 10.

Iterable<Image> images = limit(concat(featuredImages, albumImages), 10)

But how can I obtain the albumImages in the right order (round-robin)? I need a custom , then I have written this one:

public class RoundRobinIterable<T> implements Iterable<T> {
    private final Iterable<Iterable<T>> iterables;
    public RoundRobinIterable(Iterable<Iterable<T>> iterables) {
        this.iterables = iterables;
    public Iterator<T> iterator() {
        final Iterator<Iterator<T>> it = cycle(filter(
        return new UnmodifiableIterator<T>() {
            public boolean hasNext() {
                return it.hasNext();
            public T next() {
    private enum HasNext implements Predicate<Iterator<?>> {
        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>>() {
            public Iterator<T> apply(Iterable<T> input) {
                return input.iterator();

It leverage on the lazy evaluation of so the will cycle over the given iterator, skipping the empty iterators on the fly.

And that’s it. Well actually no, we want a test, don’t we?

public class RoundRobinIterableTest {
    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));

The full code is available at the gist

Happy coding!

Leave a Comment