This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 1176309de4 GROOVY-11599: Make DGM#chop(Iterator, int...) lazy
1176309de4 is described below

commit 1176309de4b42b665536f0dc5d88a9cb459e3152
Author: Paul King <[email protected]>
AuthorDate: Fri Apr 4 01:14:26 2025 +1000

    GROOVY-11599: Make DGM#chop(Iterator, int...) lazy
---
 .../groovy/runtime/ArrayGroovyMethods.java         | 16 +++---
 .../groovy/runtime/DefaultGroovyMethods.java       | 61 +++++++++++++++++-----
 2 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java 
b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
index f274c31ab9..105aa2e4a8 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
@@ -662,7 +662,7 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * @since 5.0.0
      */
     public static List<List<Boolean>> chop(boolean[] self, int... chopSizes) {
-        return DefaultGroovyMethods.chop(new BooleanArrayIterator(self), 
chopSizes);
+        return DefaultGroovyMethods.toList(DefaultGroovyMethods.chop(new 
BooleanArrayIterator(self), chopSizes));
     }
 
     /**
@@ -681,7 +681,7 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * @since 5.0.0
      */
     public static List<List<Byte>> chop(byte[] self, int... chopSizes) {
-        return DefaultGroovyMethods.chop(new ByteArrayIterator(self), 
chopSizes);
+        return DefaultGroovyMethods.toList(DefaultGroovyMethods.chop(new 
ByteArrayIterator(self), chopSizes));
     }
 
     /**
@@ -700,7 +700,7 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * @since 5.0.0
      */
     public static List<List<Character>> chop(char[] self, int... chopSizes) {
-        return DefaultGroovyMethods.chop(new CharArrayIterator(self), 
chopSizes);
+        return DefaultGroovyMethods.toList(DefaultGroovyMethods.chop(new 
CharArrayIterator(self), chopSizes));
     }
 
     /**
@@ -719,7 +719,7 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * @since 5.0.0
      */
     public static List<List<Short>> chop(short[] self, int... chopSizes) {
-        return DefaultGroovyMethods.chop(new ShortArrayIterator(self), 
chopSizes);
+        return DefaultGroovyMethods.toList(DefaultGroovyMethods.chop(new 
ShortArrayIterator(self), chopSizes));
     }
 
     /**
@@ -738,7 +738,7 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * @since 5.0.0
      */
     public static List<List<Integer>> chop(int[] self, int... chopSizes) {
-        return DefaultGroovyMethods.chop(new IntArrayIterator(self), 
chopSizes);
+        return DefaultGroovyMethods.toList(DefaultGroovyMethods.chop(new 
IntArrayIterator(self), chopSizes));
     }
 
     /**
@@ -757,7 +757,7 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * @since 5.0.0
      */
     public static List<List<Long>> chop(long[] self, int... chopSizes) {
-        return DefaultGroovyMethods.chop(new LongArrayIterator(self), 
chopSizes);
+        return DefaultGroovyMethods.toList(DefaultGroovyMethods.chop(new 
LongArrayIterator(self), chopSizes));
     }
 
     /**
@@ -776,7 +776,7 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * @since 5.0.0
      */
     public static List<List<Float>> chop(float[] self, int... chopSizes) {
-        return DefaultGroovyMethods.chop(new FloatArrayIterator(self), 
chopSizes);
+        return DefaultGroovyMethods.toList(DefaultGroovyMethods.chop(new 
FloatArrayIterator(self), chopSizes));
     }
 
     /**
@@ -795,7 +795,7 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * @since 5.0.0
      */
     public static List<List<Double>> chop(double[] self, int... chopSizes) {
-        return DefaultGroovyMethods.chop(new DoubleArrayIterator(self), 
chopSizes);
+        return DefaultGroovyMethods.toList(DefaultGroovyMethods.chop(new 
DoubleArrayIterator(self), chopSizes));
     }
 
     /**
diff --git 
a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java 
b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 9d26c3dfff..058f822ef8 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -1828,7 +1828,18 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * @since 2.5.2
      */
     public static <T> List<List<T>> chop(Iterable<T> self, int... chopSizes) {
-        return chop(self.iterator(), chopSizes);
+        return toList(chop(self.iterator(), chopSizes));
+    }
+
+    /**
+     * Chops the iterator items into pieces, returning lists with sizes 
corresponding to the supplied chop sizes.
+     *
+     * @deprecated
+     * @since 2.5.2
+     */
+    @Deprecated
+    public static <T> List<List<T>> chop$$bridge(Iterator<T> self, int... 
chopSizes) {
+        return toList(chop(self, chopSizes));
     }
 
     /**
@@ -1838,26 +1849,52 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * <p>
      * Example usage:
      * <pre class="groovyTestCase">
-     * assert (1..6).iterator().chop(1, 2, -1) == [[1], [2, 3], [4, 5, 6]]
+     * assert (1..6).iterator().chop(1, 2, -1).collect() == [[1], [2, 3], [4, 
5, 6]]
      * </pre>
      *
      * @param self      an Iterator to be chopped
      * @param chopSizes the sizes for the returned pieces
-     * @return a list of lists chopping the original iterator elements into 
pieces determined by chopSizes
-     * @since 2.5.2
+     * @return an iterator of lists chopping the original iterator elements 
into pieces determined by chopSizes
+     * @since 5.0.0
      */
-    public static <T> List<List<T>> chop(Iterator<T> self, int... chopSizes) {
+    public static <T> Iterator<List<T>> chop(Iterator<T> self, int... 
chopSizes) {
         Objects.requireNonNull(self);
-        List<List<T>> result = new ArrayList<>();
-        for (int nextSize : chopSizes) {
-            int size = nextSize;
+        return new ChopIterator<>(self, chopSizes);
+    }
+
+    private static final class ChopIterator<T> implements Iterator<List<T>> {
+        private final Iterator<T> delegate;
+        private final Queue<Integer> remainingSizes = new LinkedList<>();
+
+        private ChopIterator(Iterator<T> delegate, int... chopSizes) {
+            this.delegate = delegate;
+            int count = chopSizes.length;
+            for (int i : chopSizes) {
+                --count;
+                remainingSizes.offer(i);
+            }
+        }
+
+        @Override
+        public boolean hasNext() {
+            return !remainingSizes.isEmpty();
+        }
+
+        @Override
+        public List<T> next() {
+            if (!hasNext()) throw new NoSuchElementException();
+            int size = remainingSizes.poll();
             List<T> next = new ArrayList<>();
-            while (size-- != 0 && self.hasNext()) {
-                next.add(self.next());
+            while (size-- != 0 && delegate.hasNext()) {
+                next.add(delegate.next());
             }
-            result.add(next);
+            return next;
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
         }
-        return result;
     }
 
     
//--------------------------------------------------------------------------

Reply via email to