diff --git a/src/main/java/spliterators/part3/exercise/ZipWithArraySpliterator.java b/src/main/java/spliterators/part3/exercise/ZipWithArraySpliterator.java index 292137e..2c38c1d 100755 --- a/src/main/java/spliterators/part3/exercise/ZipWithArraySpliterator.java +++ b/src/main/java/spliterators/part3/exercise/ZipWithArraySpliterator.java @@ -1,48 +1,86 @@ package spliterators.part3.exercise; +import java.util.Optional; import java.util.Spliterator; import java.util.Spliterators; import java.util.function.Consumer; public class ZipWithArraySpliterator extends Spliterators.AbstractSpliterator> { - private final Spliterator inner; + private int currentIndex; + private final B[] array; + private int arrayStartIndex; + private int arrayEndIndex; public ZipWithArraySpliterator(Spliterator inner, B[] array) { - super(Long.MAX_VALUE, 0); // FIXME: - // TODO - throw new UnsupportedOperationException(); + this(0, inner, 0, 0, array); + + } + + private ZipWithArraySpliterator(int currentIndex, Spliterator inner, + int arrayStartIndex, int arrayEndIndex, B[] array) { + super(inner.estimateSize(), ORDERED | SIZED | SUBSIZED | NONNULL | CONCURRENT); + this.inner = inner; + this.array = array; + this.currentIndex = currentIndex; + this.arrayStartIndex = arrayStartIndex; + this.arrayEndIndex = arrayEndIndex; } @Override public int characteristics() { - // TODO - throw new UnsupportedOperationException(); + return ORDERED | SIZED | SUBSIZED | NONNULL | CONCURRENT; } @Override public boolean tryAdvance(Consumer> action) { - // TODO - throw new UnsupportedOperationException(); + if (currentIndex < array.length && + inner.tryAdvance((a) -> action.accept(new Pair<>(a, array[currentIndex])))) { + currentIndex++; + return true; + } + return false; } @Override public void forEachRemaining(Consumer> action) { - // TODO - throw new UnsupportedOperationException(); + while (currentIndex < array.length && + inner.tryAdvance(a -> action.accept(new Pair<>(a, array[currentIndex])))) { + currentIndex++; + } } @Override public Spliterator> trySplit() { - // TODO - throw new UnsupportedOperationException(); + if (inner.hasCharacteristics(SUBSIZED)) { + return Optional.ofNullable(inner.trySplit()) + .map(newInner -> { + int newCurrentIndex = currentIndex; + currentIndex += (int) newInner.estimateSize(); + + arrayStartIndex = newCurrentIndex < array.length ? newCurrentIndex : array.length - 1; + arrayEndIndex = currentIndex < array.length ? currentIndex : array.length - 1; + + Spliterator> spliterator = new ZipWithArraySpliterator(newCurrentIndex, newInner, + arrayStartIndex, arrayEndIndex, array); + + arrayStartIndex = currentIndex < array.length ? currentIndex : array.length - 1; + long newSizeOfSpltr = spliterator.estimateSize(); + arrayEndIndex = newSizeOfSpltr < array.length ? (int) newSizeOfSpltr : array.length - 1; + + return spliterator; + }) + .orElse(null); + } else { + return null; + } } @Override public long estimateSize() { - // TODO - throw new UnsupportedOperationException(); + return currentIndex + inner.estimateSize(); } } + diff --git a/src/test/java/spliterators/part3/exercise/ZipWithArraySpliteratorTest.java b/src/test/java/spliterators/part3/exercise/ZipWithArraySpliteratorTest.java new file mode 100644 index 0000000..0ebd052 --- /dev/null +++ b/src/test/java/spliterators/part3/exercise/ZipWithArraySpliteratorTest.java @@ -0,0 +1,45 @@ +package spliterators.part3.exercise; + +import org.junit.Test; + +import java.util.*; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; + +public class ZipWithArraySpliteratorTest { + + private Integer[] array = {1, 2, 3}; + private Spliterator arraySpltr = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6}).spliterator(); + private ZipWithArraySpliterator zipSpltr = new ZipWithArraySpliterator<>(arraySpltr, array); + + @Test + public void testEstimatingSizeForFirstCreating() { + int expected = 6; + int actual = (int) zipSpltr.estimateSize(); + assertThat(actual, is(expected)); + } + + @Test + public void testFirstlySplitting() { + Spliterator> firstSpl = zipSpltr.trySplit(); + Spliterator> secondSpl = zipSpltr; + + assertThat((int) firstSpl.estimateSize(), is(3)); + assertThat((int) secondSpl.estimateSize(), is(6)); + + List> expectedFirstListOfSpl = Arrays.asList( + new Pair<>(1, 1), + new Pair<>(2, 2), + new Pair<>(3, 3)); + List> actualFirstListOfSpl = new ArrayList<>(); + while (firstSpl.tryAdvance(actualFirstListOfSpl::add)) ; + assertEquals(expectedFirstListOfSpl, actualFirstListOfSpl); + + List> expectedSecondListOfSpl = Collections.emptyList(); + List> actualSecondListOfSpl = new ArrayList<>(); + while (secondSpl.tryAdvance(actualSecondListOfSpl::add)) ; + assertEquals(expectedSecondListOfSpl, actualSecondListOfSpl); + } +} \ No newline at end of file