Last active
May 13, 2023 07:50
-
-
Save filosganga/7134943 to your computer and use it in GitHub Desktop.
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
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