diff --git a/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java b/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java index 678f4f5..a2ba31a 100755 --- a/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java +++ b/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java @@ -7,11 +7,11 @@ public class RectangleSpliterator extends Spliterators.AbstractIntSpliterator { - private final int innerLength; - private final int[][] array; - private final int startOuterInclusive; - private final int endOuterExclusive; - private final int startInnerInclusive; + private int innerLength; + private int[][] array; + private int startOuterInclusive; + private int endOuterExclusive; + private int startInnerInclusive; public RectangleSpliterator(int[][] array) { this(array, 0, array.length, 0); @@ -30,7 +30,14 @@ private RectangleSpliterator(int[][] array, int startOuterInclusive, int endOute @Override public OfInt trySplit() { // TODO - throw new UnsupportedOperationException(); + final int outerLen = endOuterExclusive - startOuterInclusive; + if (outerLen <= 1) return null; + + final int outerMid = startOuterInclusive + outerLen/2; + + final RectangleSpliterator res = new RectangleSpliterator(array, startOuterInclusive, outerMid, startInnerInclusive); + startOuterInclusive = outerMid; + return res; } @Override @@ -40,7 +47,26 @@ public long estimateSize() { @Override public boolean tryAdvance(IntConsumer action) { + if (startOuterInclusive >= endOuterExclusive + && startInnerInclusive >= innerLength) + return false; + + for (int i = startInnerInclusive; i < innerLength; i++) { + final int value = array[startOuterInclusive][startInnerInclusive]; + startInnerInclusive++; + action.accept(value); + } + + return true; + } + + @Override + public void forEachRemaining(IntConsumer action) { // TODO - throw new UnsupportedOperationException(); + for (int i = startOuterInclusive; i < endOuterExclusive; i++) + for (int j = startInnerInclusive; j < innerLength; j++) + action.accept(array[i][j]); + + startOuterInclusive = endOuterExclusive; } } diff --git a/src/test/java/spliterators/part2/exercise/RectanbleSpliteratorTest.java b/src/test/java/spliterators/part2/exercise/RectanbleSpliteratorTest.java new file mode 100644 index 0000000..305be35 --- /dev/null +++ b/src/test/java/spliterators/part2/exercise/RectanbleSpliteratorTest.java @@ -0,0 +1,105 @@ +package spliterators.part2.exercise; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.Test; + +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.StreamSupport; +import spliterators.part1.exercise.RectangleSpliterator; + +import static org.junit.Assert.assertEquals; + +public class RectanbleSpliteratorTest { + private int[][] getRandomArray(int width, int height) { + final int[][] result = new int[width][height]; + + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + result[i][j] = ThreadLocalRandom.current().nextInt(); + } + } + + return result; + } + + private static class Pair { + private F first; + private S second; + Pair(F first, S second) { + this.first = first; + this.second = second; + } + public F getFirst() { return first; } + public S getSecond() { return second; } + @Override + public String toString() { + return new ToStringBuilder(this) + .append("first", first) + .append("second", second) + .toString(); + } + @Override + public boolean equals(Object p) { + return Pair.class.isInstance(p) && + this.first.equals(((Pair) p).first) + && this.second.equals(((Pair) p).second); + } + } + + @Test + public void comparePair() { + int width = 203, height = 104; + final int[][] randomArray = getRandomArray(width, height); + + Integer expected = 0; + for (int[] ints : randomArray) { + for (int i : ints) { + expected += i + 1; + } + } + + final Pair actual = + StreamSupport.stream(new RectangleSpliterator(randomArray), true) + .map(p -> new Pair<>(p + 1, p.toString())) + .reduce((p1, p2) -> new Pair<>(p1.getFirst() + p2.getFirst(), "String")) + .orElse(new Pair<>(0, "")); + + assertEquals(expected, actual.getFirst()); + } + + @Test + public void zeroLength() { + int width = 0, height = 0; + final int[][] randomArray = getRandomArray(width, height); + + final Pair expected = new Pair<>(0, ""); + + final Pair actual = + StreamSupport.stream(new RectangleSpliterator(randomArray), true) + .map(p -> new Pair<>(p + 1, p.toString())) + .reduce((p1, p2) -> new Pair<>(p1.getFirst() + p2.getFirst(), "String")) + .orElse(new Pair<>(0, "")); + + assertEquals(expected, actual); + } + + @Test + public void compareInts() { + int width = 100, height = 100; + final int[][] randomArray = getRandomArray(width, height); + + Integer expected = 0; + for (int[] ints : randomArray) { + for (int i : ints) { + expected += i; + } + } + + final Integer actual = + StreamSupport.stream(new RectangleSpliterator(randomArray), true) + .reduce((p1, p2) -> p1 + p2) + .orElse(0); + + assertEquals(expected, actual); + } +}