diff --git a/src/main/java/spliterators/part2/exercise/ZipWithIndexDoubleSpliterator.java b/src/main/java/spliterators/part2/exercise/ZipWithIndexDoubleSpliterator.java index deb4867..3acf7b4 100755 --- a/src/main/java/spliterators/part2/exercise/ZipWithIndexDoubleSpliterator.java +++ b/src/main/java/spliterators/part2/exercise/ZipWithIndexDoubleSpliterator.java @@ -2,55 +2,70 @@ import java.util.Spliterator; import java.util.Spliterators; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; public class ZipWithIndexDoubleSpliterator extends Spliterators.AbstractSpliterator { private final OfDouble inner; - private int currentIndex; + private AtomicLong currentIndex; public ZipWithIndexDoubleSpliterator(OfDouble inner) { this(0, inner); } - private ZipWithIndexDoubleSpliterator(int firstIndex, OfDouble inner) { + private ZipWithIndexDoubleSpliterator(long firstIndex, OfDouble inner) { super(inner.estimateSize(), inner.characteristics()); - currentIndex = firstIndex; + if (! inner.hasCharacteristics(SUBSIZED)) throw new IllegalStateException("Zip got not subsized Spliterator"); + currentIndex = new AtomicLong(firstIndex); this.inner = inner; } @Override public int characteristics() { - // TODO - throw new UnsupportedOperationException(); + int characteristics = inner.characteristics(); + characteristics &= ~SORTED; + return characteristics; } @Override public boolean tryAdvance(Consumer action) { // TODO - throw new UnsupportedOperationException(); + final boolean res = + inner.tryAdvance((Double v) -> + action.accept(new IndexedDoublePair((int)currentIndex.get(), v))); + if (res) currentIndex.incrementAndGet(); + return res; } @Override public void forEachRemaining(Consumer action) { // TODO - throw new UnsupportedOperationException(); + inner.forEachRemaining((Double v) -> { + action.accept(new IndexedDoublePair((int)currentIndex.get(), v)); + currentIndex.incrementAndGet(); + }); } @Override public Spliterator trySplit() { // TODO - // if (inner.hasCharacteristics(???)) { - // use inner.trySplit - // } else - - return super.trySplit(); + if (inner.hasCharacteristics(SUBSIZED)) { + OfDouble newSplit = inner.trySplit(); + if (newSplit == null) + return null; + Spliterator zipped = + new ZipWithIndexDoubleSpliterator(currentIndex.get(), newSplit); + currentIndex.addAndGet(newSplit.estimateSize()); + return zipped; + } else return super.trySplit(); } @Override public long estimateSize() { // TODO - throw new UnsupportedOperationException(); + return inner.estimateSize(); } } diff --git a/src/test/java/spliterators/part2/example/ZipWithIndexDoubleSpliteratorTest.java b/src/test/java/spliterators/part2/example/ZipWithIndexDoubleSpliteratorTest.java new file mode 100644 index 0000000..30805c6 --- /dev/null +++ b/src/test/java/spliterators/part2/example/ZipWithIndexDoubleSpliteratorTest.java @@ -0,0 +1,49 @@ +package spliterators.part2.example; + +import org.junit.Test; +import spliterators.part2.exercise.ZipWithIndexDoubleSpliterator; +import spliterators.part3.exercise.Pair; + +import java.util.List; +import java.util.Spliterators; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class ZipWithIndexDoubleSpliteratorTest { + private double[] getRandomArray(int length) { + final double[] result = new double[length]; + + for (int i = 0; i < length; i++) + result[i] = ThreadLocalRandom.current().nextInt(); + + return result; + } + + @Test + public void nonzeroLengthSuccess() { + final double[] randomArray = getRandomArray(10); + + final List collect = StreamSupport.stream(new ZipWithIndexDoubleSpliterator( + Spliterators.spliterator(randomArray, 0)), true) + .map(p -> new Pair<>(p.getIndex() + 1, p.getValue() + 1)) + .map(Pair::toString) + .collect(Collectors.toList()); + assertThat(collect.size(), is(10)); + } + + @Test + public void zeroLengthSuccess() { + final double[] randomArray = getRandomArray(0); + + final List collect = StreamSupport.stream(new ZipWithIndexDoubleSpliterator( + Spliterators.spliterator(randomArray, 0)), true) + .map(p -> new Pair<>(p.getIndex() + 1, p.getValue() + 1)) + .map(Pair::toString) + .collect(Collectors.toList()); + assertThat(collect.size(), is(0)); + } +}