From 28075ba3b5b1af03b6056735ae32bd54d435a1bb Mon Sep 17 00:00:00 2001
From: Aleksei Litkovetc <aleksei_litkovetc@epam.com>
Date: Mon, 1 May 2017 22:33:38 +0300
Subject: [PATCH] Part 1 RectangleSpliterator

---
 .../part1/exercise/RectangleSpliterator.java  | 34 +++++++++++----
 .../part1/example/ArrayExampleTest.java       | 18 ++++++++
 .../exercise/RectangleSpliteratorTest.java    | 42 +++++++++++++++++++
 3 files changed, 86 insertions(+), 8 deletions(-)
 create mode 100644 src/test/java/spliterators/part1/example/ArrayExampleTest.java
 create mode 100644 src/test/java/spliterators/part1/exercise/RectangleSpliteratorTest.java

diff --git a/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java b/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java
index 678f4f5..96653bf 100755
--- a/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java
+++ b/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java
@@ -1,6 +1,5 @@
 package spliterators.part1.exercise;
 
-
 import java.util.Spliterator;
 import java.util.Spliterators;
 import java.util.function.IntConsumer;
@@ -9,11 +8,11 @@ public class RectangleSpliterator extends Spliterators.AbstractIntSpliterator {
 
     private final int innerLength;
     private final int[][] array;
-    private final int startOuterInclusive;
+    private int startOuterInclusive;
     private final int endOuterExclusive;
-    private final int startInnerInclusive;
+    private int startInnerInclusive;
 
-    public RectangleSpliterator(int[][] array) {
+    RectangleSpliterator(int[][] array) {
         this(array, 0, array.length, 0);
     }
 
@@ -29,8 +28,18 @@ private RectangleSpliterator(int[][] array, int startOuterInclusive, int endOute
 
     @Override
     public OfInt trySplit() {
-        // TODO
-        throw new UnsupportedOperationException();
+        int length = endOuterExclusive - startOuterInclusive;
+        if (length <= 1) {
+            return null;
+        }
+
+        int middle = startOuterInclusive + length/2;
+
+        final RectangleSpliterator newSpliterator = new RectangleSpliterator(array, startOuterInclusive, middle, startInnerInclusive);
+
+        startOuterInclusive = middle;
+
+        return newSpliterator;
     }
 
     @Override
@@ -40,7 +49,16 @@ public long estimateSize() {
 
     @Override
     public boolean tryAdvance(IntConsumer action) {
-        // TODO
-        throw new UnsupportedOperationException();
+        if (startInnerInclusive >= innerLength) {
+            if (startOuterInclusive < endOuterExclusive - 1) {
+                startOuterInclusive += 1;
+                startInnerInclusive = 0;
+            } else {
+                return false;
+            }
+        }
+        action.accept(array[startOuterInclusive][startInnerInclusive]);
+        startInnerInclusive += 1;
+        return true;
     }
 }
diff --git a/src/test/java/spliterators/part1/example/ArrayExampleTest.java b/src/test/java/spliterators/part1/example/ArrayExampleTest.java
new file mode 100644
index 0000000..035e88f
--- /dev/null
+++ b/src/test/java/spliterators/part1/example/ArrayExampleTest.java
@@ -0,0 +1,18 @@
+package spliterators.part1.example;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.stream.StreamSupport;
+
+public class ArrayExampleTest {
+    @Test
+    public void IntArraySpliterator() {
+        int[] array = new int[] {1, 2, 3, 4, 5};
+        final boolean parallel = false;
+        long res = StreamSupport.intStream(new ArrayExample.IntArraySpliterator(array), parallel)
+                .asLongStream()
+                .sum();
+        Assert.assertEquals(15L, res);
+    }
+}
diff --git a/src/test/java/spliterators/part1/exercise/RectangleSpliteratorTest.java b/src/test/java/spliterators/part1/exercise/RectangleSpliteratorTest.java
new file mode 100644
index 0000000..48c1d66
--- /dev/null
+++ b/src/test/java/spliterators/part1/exercise/RectangleSpliteratorTest.java
@@ -0,0 +1,42 @@
+package spliterators.part1.exercise;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.stream.StreamSupport;
+
+import static org.junit.Assert.assertEquals;
+
+public class RectangleSpliteratorTest {
+    private int[][] array;
+
+    @Before
+    public void setup() {
+        int outerLength = 2;
+        array = new int[outerLength][];
+        for (int i = 0; i < array.length; i++) {
+            int innerLength = 2;
+            int[] inner = new int[innerLength];
+            array[i] = inner;
+            for (int j = 0; j < inner.length; j++) {
+                inner[j] = ThreadLocalRandom.current().nextInt();
+            }
+        }
+    }
+
+    @Test
+    public void testIt(){
+        long sum1 = Arrays.stream(array)
+                .parallel()
+                .flatMapToInt(Arrays::stream)
+                .asLongStream()
+                .sum();
+
+        long sum = StreamSupport.intStream(new RectangleSpliterator(array), true)
+                .asLongStream()
+                .sum();
+        assertEquals(sum1, sum);
+    }
+}
\ No newline at end of file