ラウンドロビン的なものが欲しくなったので書いてみた。
一応スレッドセーフにはしてるつもりなんだけど、これでいけるのかは実際に動かしてみないと、わからないです。
Java8の無限ストリーム使うとどうなるかはまだ考え中。
code
package me.masahito; import java.util.Iterator; import java.util.List; public class RoundRobin<T> implements Iterable<T> { private final List<T> list; private final int listSize; private RoundRobin(final Builder<T> builder) { this.list = builder.list; this.listSize = builder.list.size(); } @Override public final Iterator<T> iterator() { return new Iterator<T>() { private int index = 0; private final Object lock = new Object(); public T next() { final T result; synchronized (lock) { result = list.get(index); index = (index + 1) % listSize; } return result; } public boolean hasNext() { return true; } public void remove() { throw new UnsupportedOperationException(); } }; } public static class Builder<T> { private final List<T> list; public Builder(final List<T> list) { this.list = list; } public final Iterator<T> build() { return new RoundRobin<>(this).iterator(); } } }
unittest
package me.masahito; import org.junit.Test; import java.util.Arrays; import java.util.Iterator; import java.util.List; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; /** * RoundRobin Test */ public class RoundRobinTest { @Test public void buildRoundRobinIterator() throws Exception { final List<Integer> list = Arrays.asList(1, 2, 3); final Iterator<Integer> ite = new RoundRobin.Builder<>(list).build(); assertThat(ite.next(), is(equalTo(1))); assertThat(ite.next(), is(equalTo(2))); assertThat(ite.next(), is(equalTo(3))); assertThat(ite.next(), is(equalTo(1))); } }