From eaa36a59ca4b766ce01d08f96523b2e9486fa5ab Mon Sep 17 00:00:00 2001 From: Aleksei Litkovetc Date: Mon, 1 May 2017 22:51:50 +0300 Subject: [PATCH] Part 3 ZipWithArraySpliterator --- .../exercise/ZipWithArraySpliterator.java | 53 +++++++---- .../exercise/ZipWithArraySpliteratorTest.java | 87 +++++++++++++++++++ 2 files changed, 124 insertions(+), 16 deletions(-) create mode 100644 src/test/java/spliterators/part3/exercise/ZipWithArraySpliteratorTest.java diff --git a/src/main/java/spliterators/part3/exercise/ZipWithArraySpliterator.java b/src/main/java/spliterators/part3/exercise/ZipWithArraySpliterator.java index 292137e..28b256f 100755 --- a/src/main/java/spliterators/part3/exercise/ZipWithArraySpliterator.java +++ b/src/main/java/spliterators/part3/exercise/ZipWithArraySpliterator.java @@ -5,44 +5,65 @@ import java.util.function.Consumer; public class ZipWithArraySpliterator extends Spliterators.AbstractSpliterator> { - - private final Spliterator inner; private final B[] array; + private int index; public ZipWithArraySpliterator(Spliterator inner, B[] array) { - super(Long.MAX_VALUE, 0); // FIXME: - // TODO - throw new UnsupportedOperationException(); + this(inner, array, 0); + } + + public ZipWithArraySpliterator(Spliterator inner, B[] array, int index) { + super(Math.min(inner.estimateSize(), array.length - index), inner.characteristics()); + this.inner = inner; + this.array = array; + this.index = index; } @Override public int characteristics() { - // TODO - throw new UnsupportedOperationException(); + return inner.characteristics() & ~Spliterator.SORTED; } @Override public boolean tryAdvance(Consumer> action) { - // TODO - throw new UnsupportedOperationException(); + return index < array.length && inner.tryAdvance(a -> { + Pair pair = new Pair<>(a, array[index]); + index += 1; + action.accept(pair); + }); } @Override public void forEachRemaining(Consumer> action) { - // TODO - throw new UnsupportedOperationException(); + if (inner.hasCharacteristics(SIZED) && inner.estimateSize() <= array.length - index) { + inner.forEachRemaining(a -> { + Pair pair = new Pair<>(a, array[index]); + index += 1; + action.accept(pair); + }); + } else { + super.forEachRemaining(action); + } } @Override public Spliterator> trySplit() { - // TODO - throw new UnsupportedOperationException(); + if (inner.hasCharacteristics(SUBSIZED)) { + Spliterator split = inner.trySplit(); + if (split == null) { + return null; + } + final ZipWithArraySpliterator spliterator = new ZipWithArraySpliterator<>(split, array, index); + index = Math.min((int) (index + split.estimateSize()), array.length); + return spliterator; + } else { + return super.trySplit(); + } } @Override public long estimateSize() { - // TODO - throw new UnsupportedOperationException(); + return Math.min(inner.estimateSize(), array.length - index); } -} +} \ No newline at end of file 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..2abf677 --- /dev/null +++ b/src/test/java/spliterators/part3/exercise/ZipWithArraySpliteratorTest.java @@ -0,0 +1,87 @@ +package spliterators.part3.exercise; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class ZipWithArraySpliteratorTest { + @Test + public void tryAdvanceTest() { + Stream stream = Stream.of(1, 2, 3); + String[] array = generateArray(5); + ZipWithArraySpliterator spliterator = new ZipWithArraySpliterator<>(stream.spliterator(), array); + spliterator.tryAdvance(p -> assertEquals(new Pair<>(1, array[0]), p)); + + assertEquals(2, spliterator.estimateSize()); + } + + @Test + public void trySplitTest() { + Stream stream = Stream.of(1, 2, 3); + String[] array = {"d", "b", "z"}; + List> expected = Arrays.asList(new Pair<>(1, "d"), new Pair<>(2, "b"), new Pair<>(3, "z")); + ZipWithArraySpliterator spliterator = new ZipWithArraySpliterator<>(stream.spliterator(), array); + long originSize = spliterator.estimateSize(); + Spliterator> spliterator1 = spliterator.trySplit(); + long size = spliterator.estimateSize(); + long size1 = spliterator1.estimateSize(); + List> list1 = StreamSupport.stream(spliterator1, false).collect(Collectors.toList()); + List> list2 = StreamSupport.stream(spliterator, false).collect(Collectors.toList()); + list1.addAll(list2); + + assertEquals(originSize, size + size1); + assertEquals(expected, list1); + } + + @Test + public void emptyStreamTest(){ + String[] array = {"dbz"}; + Stream empty = Stream.empty(); + ZipWithArraySpliterator spliterator = new ZipWithArraySpliterator<>(empty.spliterator(), array); + + assertEquals(0, spliterator.estimateSize()); + assertNull(spliterator.trySplit()); + } + + @Test + public void forEachRemainingTest() { + Stream stream = Stream.of(1, 2); + String[] array = {"John", "Ace", "Danny", "Felix"}; + ZipWithArraySpliterator spliterator = new ZipWithArraySpliterator<>(stream.spliterator(), array); + List> expected = Arrays.asList(new Pair<>(1, "John"), new Pair<>(2, "Ace")); + List> result = new ArrayList<>(); + spliterator.forEachRemaining(result::add); + + assertEquals(expected, result); + assertFalse(spliterator.tryAdvance(System.out::print)); + } + + @Test + public void spliteratorStreamTest() { + final String[] array = {"1", "2", "3"}; + Stream stream = Stream.of(1, 2, 3); + Stream> pairStream = StreamSupport.stream( + new ZipWithArraySpliterator<>(stream.spliterator(), array), + true); + int sum = pairStream + .mapToInt(value -> value.getA() + Integer.parseInt(value.getB())) + .sum(); + + assertEquals(12, sum); + } + + private String[] generateArray(int size) { + Random rand = new Random(); + final String[] result = new String[size]; + for (int i = 0; i < size; i++) { + result[i] = String.valueOf(rand.nextInt()); + } + return result; + } +} \ No newline at end of file