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

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-collections.git


The following commit(s) were added to refs/heads/master by this push:
     new c8cd99e43 [COLLECTIONS-869] Add 
org.apache.commons.collections4.IteratorUtils.chainedIterator(Iterator<? 
extends Iterator<? extends E>>)
c8cd99e43 is described below

commit c8cd99e4310e25dd595adb199f70a5401705c53d
Author: Gary Gregory <[email protected]>
AuthorDate: Sat Oct 19 11:38:23 2024 -0400

    [COLLECTIONS-869] Add
    org.apache.commons.collections4.IteratorUtils.chainedIterator(Iterator<?
    extends Iterator<? extends E>>)
---
 src/changes/changes.xml                            |  2 +
 .../apache/commons/collections4/IteratorUtils.java | 22 +++++++
 .../commons/collections4/IteratorUtilsTest.java    | 67 +++++++++++++++-------
 3 files changed, 71 insertions(+), 20 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index b2dde9c3d..eed23d6da 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -51,6 +51,8 @@
     <action type="add" dev="ggregory" due-to="Gary Gregory">Add missing 
methods in AbstractMapTests.</action>
     <action type="add" issue="COLLECTIONS-700" dev="ggregory" due-to="Gary 
Gregory">Add ConcurrentReferenceHashMap.</action>
     <action type="add" dev="ggregory" due-to="Gary Gregory">Add 
commons.easymock.version to parameterize EasyMock version.</action>
+    <action type="add" issue="COLLECTIONS-869" dev="ggregory" due-to="Gary 
Gregory">Add 
org.apache.commons.collections4.IteratorUtils.chainedIterator(Iterator&lt;? 
extends Iterator&lt;? extends E&gt;&gt;).</action>
+
     <!-- UPDATE -->
     <action type="update" issue="COLLECTIONS-857" dev="ggregory" 
due-to="Claude Warren">Update bloom filter documentation #508.</action>
     <action type="update" dev="ggregory" due-to="Dependabot, Gary 
Gregory">Bump commons-codec:commons-codec from 1.17.0 to 1.17.1 #514.</action>
diff --git a/src/main/java/org/apache/commons/collections4/IteratorUtils.java 
b/src/main/java/org/apache/commons/collections4/IteratorUtils.java
index 75fcaf5ae..ac21499be 100644
--- a/src/main/java/org/apache/commons/collections4/IteratorUtils.java
+++ b/src/main/java/org/apache/commons/collections4/IteratorUtils.java
@@ -46,6 +46,7 @@ import 
org.apache.commons.collections4.iterators.FilterListIterator;
 import org.apache.commons.collections4.iterators.IteratorChain;
 import org.apache.commons.collections4.iterators.IteratorEnumeration;
 import org.apache.commons.collections4.iterators.IteratorIterable;
+import org.apache.commons.collections4.iterators.LazyIteratorChain;
 import org.apache.commons.collections4.iterators.ListIteratorWrapper;
 import org.apache.commons.collections4.iterators.LoopingIterator;
 import org.apache.commons.collections4.iterators.LoopingListIterator;
@@ -426,6 +427,27 @@ public class IteratorUtils {
         return new IteratorChain<>(iterators);
     }
 
+    /**
+     * Gets an iterator that iterates through an {@link Iterator} of Iterators 
one after another.
+     *
+     * @param <E>       the element type
+     * @param iterators the iterators to use, not null or empty or contain 
nulls
+     * @return a combination iterator over the iterators
+     * @throws NullPointerException if iterators collection is null or 
contains a null
+     * @throws ClassCastException   if the iterators collection contains the 
wrong object type
+     * @since 4.5.0-M3
+     */
+    public static <E> Iterator<E> chainedIterator(final Iterator<? extends 
Iterator<? extends E>> iterators) {
+        return new LazyIteratorChain<E>() {
+
+            @Override
+            protected Iterator<? extends E> nextIterator(final int count) {
+                return iterators.hasNext() ? iterators.next() : null;
+            }
+
+        };
+    }
+
     /**
      * Gets an iterator that iterates through an array of {@link Iterator}s
      * one after another.
diff --git 
a/src/test/java/org/apache/commons/collections4/IteratorUtilsTest.java 
b/src/test/java/org/apache/commons/collections4/IteratorUtilsTest.java
index 05e2347c8..820a70b29 100644
--- a/src/test/java/org/apache/commons/collections4/IteratorUtilsTest.java
+++ b/src/test/java/org/apache/commons/collections4/IteratorUtilsTest.java
@@ -435,6 +435,26 @@ public class IteratorUtilsTest {
                 "Expecting NullPointerException");
     }
 
+    @Test
+    public void testChainedIteratorArrayOfIterator() {
+        // String
+        final IteratorChainTest iteratorChainTest = new IteratorChainTest();
+        iteratorChainTest.setUp();
+        // @formateter:off
+        final Iterator<String> iterator = IteratorUtils.chainedIterator(
+                iteratorChainTest.getList1().iterator(),
+                iteratorChainTest.getList2().iterator(),
+                iteratorChainTest.getList3().iterator());
+        // @formateter:on
+        assertEquals("One", iterator.next());
+        assertEquals("Two", iterator.next());
+        assertEquals("Three", iterator.next());
+        assertEquals("Four", iterator.next());
+        assertEquals("Five", iterator.next());
+        assertEquals("Six", iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
     @Test
     public void testChainedIteratorList() {
         final IteratorChainTest iteratorChainTest = new IteratorChainTest();
@@ -452,6 +472,33 @@ public class IteratorUtilsTest {
         assertEquals(actual, expected);
     }
 
+    @Test
+    public void testChainedIteratorOfIterators() {
+        final List<List<Number>> lst = new ArrayList<>();
+        final List<Integer> iList = Arrays.asList(1, 3);
+        lst.add(Arrays.asList(3.14f, Math.sqrt(2.0)));
+        final Iterator<Iterator<Number>> toBeUnwound = new 
Iterator<Iterator<Number>>() {
+            List<List<Number>> lst = Arrays.asList(Arrays.asList(1, 3), 
Arrays.asList(3.14F, Math.sqrt(2.0)));
+            Iterator<List<Number>> lstIter = lst.iterator();
+
+            @Override
+            public boolean hasNext() {
+                return lstIter.hasNext();
+            }
+
+            @Override
+            public Iterator<Number> next() {
+                return lstIter.next().iterator();
+            }
+        };
+
+        final List<Number> expected = Arrays.asList(1, 3, 3.14f, 
Math.sqrt(2.0));
+        final Iterator<Number> iter = 
IteratorUtils.chainedIterator(toBeUnwound);
+        final List<Number> actual = new ArrayList<>();
+        iter.forEachRemaining(actual::add);
+        assertEquals(actual, expected);
+    }
+
     @Test
     public void testChainedIteratorRawGenerics() {
         final ArrayList arrayList = new ArrayList();
@@ -461,26 +508,6 @@ public class IteratorUtilsTest {
         assertTrue(IteratorUtils.chainedIterator(coll) instanceof Iterator, 
"create instance fail");
     }
 
-    @Test
-    public void testChainedIteratorString() {
-        // String
-        final IteratorChainTest iteratorChainTest = new IteratorChainTest();
-        iteratorChainTest.setUp();
-        // @formateter:off
-        final Iterator<String> iterator = IteratorUtils.chainedIterator(
-                iteratorChainTest.getList1().iterator(),
-                iteratorChainTest.getList2().iterator(),
-                iteratorChainTest.getList3().iterator());
-        // @formateter:on
-        assertEquals("One", iterator.next());
-        assertEquals("Two", iterator.next());
-        assertEquals("Three", iterator.next());
-        assertEquals("Four", iterator.next());
-        assertEquals("Five", iterator.next());
-        assertEquals("Six", iterator.next());
-        assertFalse(iterator.hasNext());
-    }
-
     /**
      * Tests methods collatedIterator(...)
      */

Reply via email to