diff --git a/src/main/java/spliterators/part2/exercise/ZipWithIndexDoubleSpliterator.java b/src/main/java/spliterators/part2/exercise/ZipWithIndexDoubleSpliterator.java index deb4867..14287b8 100755 --- a/src/main/java/spliterators/part2/exercise/ZipWithIndexDoubleSpliterator.java +++ b/src/main/java/spliterators/part2/exercise/ZipWithIndexDoubleSpliterator.java @@ -1,12 +1,13 @@ package spliterators.part2.exercise; +import java.util.Comparator; import java.util.Spliterator; import java.util.Spliterators; import java.util.function.Consumer; +import java.util.function.DoubleConsumer; public class ZipWithIndexDoubleSpliterator extends Spliterators.AbstractSpliterator { - private final OfDouble inner; private int currentIndex; @@ -22,35 +23,47 @@ private ZipWithIndexDoubleSpliterator(int firstIndex, OfDouble inner) { @Override public int characteristics() { - // TODO - throw new UnsupportedOperationException(); + return inner.characteristics(); } @Override public boolean tryAdvance(Consumer action) { - // TODO - throw new UnsupportedOperationException(); + return inner.tryAdvance(convert(action)); } @Override public void forEachRemaining(Consumer action) { - // TODO - throw new UnsupportedOperationException(); + inner.forEachRemaining(convert(action)); } @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, newSplit); + currentIndex += newSplit.estimateSize(); + return zipped; + } else { + return super.trySplit(); + } } @Override public long estimateSize() { - // TODO - throw new UnsupportedOperationException(); + return inner.getExactSizeIfKnown(); + } + + @Override + public Comparator getComparator() { + Comparator comparator = inner.getComparator(); + return comparator == null ? null : Comparator.comparing(IndexedDoublePair::getValue, comparator); + } + + private DoubleConsumer convert(Consumer action) { + return value -> action.accept(new IndexedDoublePair(currentIndex++, value)); } } diff --git a/src/test/java/spliterators/part2/exercise/ZipWithIndexDoubleSpliteratorTest.java b/src/test/java/spliterators/part2/exercise/ZipWithIndexDoubleSpliteratorTest.java new file mode 100644 index 0000000..8756bf5 --- /dev/null +++ b/src/test/java/spliterators/part2/exercise/ZipWithIndexDoubleSpliteratorTest.java @@ -0,0 +1,99 @@ +package spliterators.part2.exercise; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.Spliterator; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import static java.util.stream.Collectors.toList; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.*; + +/** + * 24.07.2017 by K.N.K + */ +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().nextDouble(); + } + + return result; + } + + @Test + public void comparePaired() { + final double[] randomArray = getRandomArray(1_000); + + final List result1 = Stream.iterate( + new IndexedDoublePair(0, randomArray[0]), + p -> new IndexedDoublePair(p.getIndex() + 1, randomArray[p.getIndex() + 1])) + .limit(randomArray.length) + .collect(toList()); + + final Spliterator.OfDouble spliterator = + Arrays.stream(randomArray).spliterator(); + final List result2 = + StreamSupport.stream(new ZipWithIndexDoubleSpliterator(spliterator), true) + .map(p -> new IndexedDoublePair(p.getIndex() + 1, p.getValue())) + .map(p -> new IndexedDoublePair(p.getIndex() - 1, p.getValue())) + .collect(toList()); + + assertEquals(result1, result2); + } + + @Test + public void testZipWithIndexSplitAndTryAdvance() throws Exception { + + double[] d = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6}; + + Spliterator.OfDouble spliterator = Arrays.stream(d).spliterator(); + + ZipWithIndexDoubleSpliterator zip = + new ZipWithIndexDoubleSpliterator(spliterator); + + Spliterator idp1 = zip.trySplit(); + + idp1.tryAdvance(pair -> { + assertEquals(0, pair.getIndex()); + assertThat(1.1, is(pair.getValue())); + }); + idp1.tryAdvance(pair -> { + assertEquals(1, pair.getIndex()); + assertThat(2.2, is(pair.getValue())); + }); + idp1.tryAdvance(pair -> { + assertEquals(2, pair.getIndex()); + assertThat(3.3, is(pair.getValue())); + }); + boolean b = idp1.tryAdvance(pair -> {}); + assertFalse(b); + + Spliterator idp2 = zip.trySplit(); + idp2.tryAdvance(pair -> { + assertEquals(3, pair.getIndex()); + assertThat(4.4, is(pair.getValue())); + }); + boolean b1 = idp2.tryAdvance(pair -> {}); + assertFalse(b1); + + zip.tryAdvance(pair -> { + assertEquals(4, pair.getIndex()); + assertThat(5.5, is(pair.getValue())); + }); + zip.tryAdvance(pair -> { + assertEquals(5, pair.getIndex()); + assertThat(6.6, is(pair.getValue())); + }); + boolean b2 = zip.tryAdvance(pair -> {}); + assertFalse(b2); + } + +} \ No newline at end of file