ラウンドロビン的なものが欲しくなったので書いてみた。
一応スレッドセーフにはしてるつもりなんだけど、これでいけるのかは実際に動かしてみないと、わからないです。
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)));
}
}