You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tn...@apache.org on 2015/05/28 11:58:10 UTC
svn commit: r1682196 - in /commons/proper/collections/trunk/src: changes/
main/java/org/apache/commons/collections4/
main/java/org/apache/commons/collections4/iterators/
test/java/org/apache/commons/collections4/iterators/
Author: tn
Date: Thu May 28 09:58:09 2015
New Revision: 1682196
URL: http://svn.apache.org/r1682196
Log:
Add unit test for ZippingIterator, add factory methods to IteratorUtils, add changelog entry.
Added:
commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/iterators/ZippingIteratorTest.java (with props)
Modified:
commons/proper/collections/trunk/src/changes/changes.xml
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/IteratorUtils.java
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/iterators/ZippingIterator.java
Modified: commons/proper/collections/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/changes/changes.xml?rev=1682196&r1=1682195&r2=1682196&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/changes/changes.xml (original)
+++ commons/proper/collections/trunk/src/changes/changes.xml Thu May 28 09:58:09 2015
@@ -28,6 +28,9 @@
added to "IterableUtils" and "IteratorUtils".
</action>
<action issue="COLLECTIONS-464" dev="tn" type="add">
+ Added new "ZippingIterator" and factory methods "IteratorUtils#zippingIterator(...)".
+ </action>
+ <action issue="COLLECTIONS-464" dev="tn" type="add">
Added new decorator "SkippingIterator" and factory methods "IteratorUtils#skippingIterator(...)".
</action>
<action issue="COLLECTIONS-556" dev="tn" type="add">
Modified: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/IteratorUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/IteratorUtils.java?rev=1682196&r1=1682195&r2=1682196&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/IteratorUtils.java (original)
+++ commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/IteratorUtils.java Thu May 28 09:58:09 2015
@@ -61,6 +61,7 @@ import org.apache.commons.collections4.i
import org.apache.commons.collections4.iterators.UnmodifiableIterator;
import org.apache.commons.collections4.iterators.UnmodifiableListIterator;
import org.apache.commons.collections4.iterators.UnmodifiableMapIterator;
+import org.apache.commons.collections4.iterators.ZippingIterator;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -489,22 +490,6 @@ public class IteratorUtils {
return new BoundedIterator<E>(iterator, offset, max);
}
- // Skipping
- //-----------------------------------------------------------------------
- /**
- * Decorates the specified iterator to skip the first N elements.
- *
- * @param <E> the element type
- * @param iterator the iterator to decorate
- * @param offset the first number of elements to skip
- * @return a new skipping iterator
- * @throws IllegalArgumentException if the iterator is null or offset is negative
- * @since 4.1
- */
- public static <E> SkippingIterator<E> skippingIterator(final Iterator<E> iterator, long offset) {
- return new SkippingIterator<E>(iterator, offset);
- }
-
// Unmodifiable
//-----------------------------------------------------------------------
/**
@@ -914,6 +899,68 @@ public class IteratorUtils {
return PushbackIterator.pushbackIterator(iterator);
}
+ // Skipping
+ //-----------------------------------------------------------------------
+ /**
+ * Decorates the specified iterator to skip the first N elements.
+ *
+ * @param <E> the element type
+ * @param iterator the iterator to decorate
+ * @param offset the first number of elements to skip
+ * @return a new skipping iterator
+ * @throws IllegalArgumentException if the iterator is null or offset is negative
+ * @since 4.1
+ */
+ public static <E> SkippingIterator<E> skippingIterator(final Iterator<E> iterator, long offset) {
+ return new SkippingIterator<E>(iterator, offset);
+ }
+
+ // Zipping
+ //-----------------------------------------------------------------------
+ /**
+ * Returns an iterator that interleaves elements from the decorated iterators.
+ *
+ * @param <E> the element type
+ * @param a the first iterator to interleave
+ * @param b the second iterator to interleave
+ * @return an iterator, interleaving the decorated iterators
+ * @throws IllegalArgumentException if any iterator is null
+ * @since 4.1
+ */
+ public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E> a, final Iterator<? extends E> b) {
+ return new ZippingIterator<E>(a, b);
+ }
+
+ /**
+ * Returns an iterator that interleaves elements from the decorated iterators.
+ *
+ * @param <E> the element type
+ * @param a the first iterator to interleave
+ * @param b the second iterator to interleave
+ * @param c the third iterator to interleave
+ * @return an iterator, interleaving the decorated iterators
+ * @throws IllegalArgumentException if any iterator is null
+ * @since 4.1
+ */
+ public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E> a,
+ final Iterator<? extends E> b,
+ final Iterator<? extends E> c) {
+ return new ZippingIterator<E>(a, b, c);
+ }
+
+ /**
+ * Returns an iterator that interleaves elements from the decorated iterators.
+ *
+ * @param <E> the element type
+ * @param iterators the array of iterators to interleave
+ * @return an iterator, interleaving the decorated iterators
+ * @throws IllegalArgumentException if any iterator is null
+ * @since 4.1
+ */
+ public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E>... iterators) {
+ return new ZippingIterator<E>(iterators);
+ }
+
// Views
//-----------------------------------------------------------------------
/**
Modified: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/iterators/ZippingIterator.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/iterators/ZippingIterator.java?rev=1682196&r1=1682195&r2=1682196&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/iterators/ZippingIterator.java (original)
+++ commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/iterators/ZippingIterator.java Thu May 28 09:58:09 2015
@@ -27,9 +27,9 @@ import org.apache.commons.collections4.F
* Provides an interleaved iteration over the elements contained in a
* collection of Iterators.
* <p>
- * Given two {@link Iterator} instances <code>A</code> and
- * <code>B</code>, the {@link #next} method on this iterator will
- * alternate between <code>A.next()</code> and <code>B.next()</code>.
+ * Given two {@link Iterator} instances {@code A} and {@code B}, the
+ * {@link #next} method on this iterator will switch between {@code A.next()}
+ * and {@code B.next()} until both iterators are exhausted.
*
* @since 4.1
* @version $Id$
@@ -38,8 +38,10 @@ public class ZippingIterator<E> implemen
/** The {@link Iterator}s to evaluate. */
private final Iterator<Iterator<? extends E>> iterators;
+
/** The next iterator to use for next(). */
private Iterator<? extends E> nextIterator = null;
+
/** The last iterator which was used for next(). */
private Iterator<? extends E> lastReturned = null;
@@ -50,8 +52,8 @@ public class ZippingIterator<E> implemen
* Constructs a new <code>ZippingIterator</code> that will provide
* interleaved iteration over the two given iterators.
*
- * @param a the first child iterator
- * @param b the second child iterator
+ * @param a the first child iterator
+ * @param b the second child iterator
* @throws NullPointerException if either iterator is null
*/
@SuppressWarnings("unchecked")
@@ -60,19 +62,34 @@ public class ZippingIterator<E> implemen
}
/**
- * Constructs a new <code>ZippingIterator</code> that will use the
- * specified comparator to provide ordered iteration over the array of
- * iterators.
+ * Constructs a new <code>ZippingIterator</code> that will provide
+ * interleaved iteration over the three given iterators.
+ *
+ * @param a the first child iterator
+ * @param b the second child iterator
+ * @param c the third child iterator
+ * @throws NullPointerException if either iterator is null
+ */
+ @SuppressWarnings("unchecked")
+ public ZippingIterator(final Iterator<? extends E> a,
+ final Iterator<? extends E> b,
+ final Iterator<? extends E> c) {
+ this(new Iterator[] {a, b, c});
+ }
+
+ /**
+ * Constructs a new <code>ZippingIterator</code> that will provide
+ * interleaved iteration of the specified iterators.
*
- * @param iterators the array of iterators
- * @throws NullPointerException if iterators array is or contains null
+ * @param iterators the array of iterators
+ * @throws NullPointerException if any iterator is null
*/
public ZippingIterator(final Iterator<? extends E>... iterators) {
- // create a mutable list
+ // create a mutable list to be able to remove exhausted iterators
final List<Iterator<? extends E>> list = new ArrayList<Iterator<? extends E>>();
- for (Iterator<? extends E> iterator : iterators) {
+ for (final Iterator<? extends E> iterator : iterators) {
if (iterator == null) {
- throw new NullPointerException("Iterator must not be null");
+ throw new NullPointerException("Iterator must not be null.");
}
list.add(iterator);
}
@@ -83,21 +100,21 @@ public class ZippingIterator<E> implemen
// -------------------------------------------------------------------
/**
- * Returns <code>true</code> if any child iterator has remaining elements.
+ * Returns {@code true} if any child iterator has remaining elements.
*
* @return true if this iterator has remaining elements
*/
public boolean hasNext() {
// the next iterator has already been determined
- // this might happen if hasNext() was called multiple
+ // this might happen if hasNext() is called multiple
if (nextIterator != null) {
return true;
}
while(iterators.hasNext()) {
- final Iterator<? extends E> iterator = iterators.next();
- if (iterator.hasNext()) {
- nextIterator = iterator;
+ final Iterator<? extends E> childIterator = iterators.next();
+ if (childIterator.hasNext()) {
+ nextIterator = childIterator;
return true;
} else {
// iterator is exhausted, remove it
Added: commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/iterators/ZippingIteratorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/iterators/ZippingIteratorTest.java?rev=1682196&view=auto
==============================================================================
--- commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/iterators/ZippingIteratorTest.java (added)
+++ commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/iterators/ZippingIteratorTest.java Thu May 28 09:58:09 2015
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.ArrayList;
+
+import org.apache.commons.collections4.IteratorUtils;
+
+/**
+ * Unit test suite for {@link ZippingIterator}.
+ *
+ * @version $Id$
+ */
+@SuppressWarnings("boxing")
+public class ZippingIteratorTest extends AbstractIteratorTest<Integer> {
+
+ //------------------------------------------------------------ Conventional
+
+ public ZippingIteratorTest(final String testName) {
+ super(testName);
+ }
+
+ //--------------------------------------------------------------- Lifecycle
+
+ private ArrayList<Integer> evens = null;
+ private ArrayList<Integer> odds = null;
+ private ArrayList<Integer> fib = null;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ evens = new ArrayList<Integer>();
+ odds = new ArrayList<Integer>();
+ for (int i = 0; i < 20; i++) {
+ if (0 == i % 2) {
+ evens.add(i);
+ } else {
+ odds.add(i);
+ }
+ }
+ fib = new ArrayList<Integer>();
+ fib.add(1);
+ fib.add(1);
+ fib.add(2);
+ fib.add(3);
+ fib.add(5);
+ fib.add(8);
+ fib.add(13);
+ fib.add(21);
+ }
+
+ //---------------------------------------------------- TestIterator Methods
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public ZippingIterator<Integer> makeEmptyIterator() {
+ return new ZippingIterator<Integer>(IteratorUtils.<Integer>emptyIterator());
+ }
+
+ @Override
+ public ZippingIterator<Integer> makeObject() {
+ return new ZippingIterator<Integer>(evens.iterator(), odds.iterator(), fib.iterator());
+ }
+
+ //------------------------------------------------------------------- Tests
+
+ public void testIterateEven() {
+ @SuppressWarnings("unchecked")
+ final ZippingIterator<Integer> iter = new ZippingIterator<Integer>(evens.iterator());
+ for (int i = 0; i < evens.size(); i++) {
+ assertTrue(iter.hasNext());
+ assertEquals(evens.get(i), iter.next());
+ }
+ assertTrue(!iter.hasNext());
+ }
+
+ public void testIterateEvenOdd() {
+ final ZippingIterator<Integer> iter = new ZippingIterator<Integer>(evens.iterator(), odds.iterator());
+ for (int i = 0; i < 20; i++) {
+ assertTrue(iter.hasNext());
+ assertEquals(Integer.valueOf(i), iter.next());
+ }
+ assertTrue(!iter.hasNext());
+ }
+
+ public void testIterateOddEven() {
+ final ZippingIterator<Integer> iter = new ZippingIterator<Integer>(odds.iterator(), evens.iterator());
+ for (int i = 0, j = 0; i < 20; i++) {
+ assertTrue(iter.hasNext());
+ int val = iter.next();
+ if (i % 2 == 0) {
+ assertEquals(odds.get(j).intValue(), val);
+ } else {
+ assertEquals(evens.get(j).intValue(), val);
+ j++;
+ }
+ }
+ assertTrue(!iter.hasNext());
+ }
+
+ public void testIterateEvenEven() {
+ final ZippingIterator<Integer> iter = new ZippingIterator<Integer>(evens.iterator(), evens.iterator());
+ for (int i = 0; i < evens.size(); i++) {
+ assertTrue(iter.hasNext());
+ assertEquals(evens.get(i), iter.next());
+ assertTrue(iter.hasNext());
+ assertEquals(evens.get(i), iter.next());
+ }
+ assertTrue(!iter.hasNext());
+ }
+
+ public void testIterateFibEvenOdd() {
+ final ZippingIterator<Integer> iter = new ZippingIterator<Integer>(fib.iterator(), evens.iterator(), odds.iterator());
+
+ assertEquals(Integer.valueOf(1),iter.next()); // fib 1
+ assertEquals(Integer.valueOf(0),iter.next()); // even 0
+ assertEquals(Integer.valueOf(1),iter.next()); // odd 1
+ assertEquals(Integer.valueOf(1),iter.next()); // fib 1
+ assertEquals(Integer.valueOf(2),iter.next()); // even 2
+ assertEquals(Integer.valueOf(3),iter.next()); // odd 3
+ assertEquals(Integer.valueOf(2),iter.next()); // fib 2
+ assertEquals(Integer.valueOf(4),iter.next()); // even 4
+ assertEquals(Integer.valueOf(5),iter.next()); // odd 5
+ assertEquals(Integer.valueOf(3),iter.next()); // fib 3
+ assertEquals(Integer.valueOf(6),iter.next()); // even 6
+ assertEquals(Integer.valueOf(7),iter.next()); // odd 7
+ assertEquals(Integer.valueOf(5),iter.next()); // fib 5
+ assertEquals(Integer.valueOf(8),iter.next()); // even 8
+ assertEquals(Integer.valueOf(9),iter.next()); // odd 9
+ assertEquals(Integer.valueOf(8),iter.next()); // fib 8
+ assertEquals(Integer.valueOf(10),iter.next()); // even 10
+ assertEquals(Integer.valueOf(11),iter.next()); // odd 11
+ assertEquals(Integer.valueOf(13),iter.next()); // fib 13
+ assertEquals(Integer.valueOf(12),iter.next()); // even 12
+ assertEquals(Integer.valueOf(13),iter.next()); // odd 13
+ assertEquals(Integer.valueOf(21),iter.next()); // fib 21
+ assertEquals(Integer.valueOf(14),iter.next()); // even 14
+ assertEquals(Integer.valueOf(15),iter.next()); // odd 15
+ assertEquals(Integer.valueOf(16),iter.next()); // even 16
+ assertEquals(Integer.valueOf(17),iter.next()); // odd 17
+ assertEquals(Integer.valueOf(18),iter.next()); // even 18
+ assertEquals(Integer.valueOf(19),iter.next()); // odd 19
+
+ assertTrue(!iter.hasNext());
+ }
+
+ public void testRemoveFromSingle() {
+ @SuppressWarnings("unchecked")
+ final ZippingIterator<Integer> iter = new ZippingIterator<Integer>(evens.iterator());
+ int expectedSize = evens.size();
+ while (iter.hasNext()) {
+ final Object o = iter.next();
+ final Integer val = (Integer) o;
+ if (val.intValue() % 4 == 0) {
+ expectedSize--;
+ iter.remove();
+ }
+ }
+ assertEquals(expectedSize, evens.size());
+ }
+
+ public void testRemoveFromDouble() {
+ final ZippingIterator<Integer> iter = new ZippingIterator<Integer>(evens.iterator(), odds.iterator());
+ int expectedSize = evens.size() + odds.size();
+ while (iter.hasNext()) {
+ final Object o = iter.next();
+ final Integer val = (Integer) o;
+ if (val.intValue() % 4 == 0 || val.intValue() % 3 == 0) {
+ expectedSize--;
+ iter.remove();
+ }
+ }
+ assertEquals(expectedSize, evens.size() + odds.size());
+ }
+
+}
+
Propchange: commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/iterators/ZippingIteratorTest.java
------------------------------------------------------------------------------
svn:keywords = Id Revision HeadURL