You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by br...@apache.org on 2011/05/25 20:04:29 UTC
svn commit: r1127604 - in /commons/proper/collections/trunk/src:
java/org/apache/commons/collections/
java/org/apache/commons/collections/iterators/
test/org/apache/commons/collections/
test/org/apache/commons/collections/iterators/
Author: brentworden
Date: Wed May 25 18:04:29 2011
New Revision: 1127604
URL: http://svn.apache.org/viewvc?rev=1127604&view=rev
Log:
COLLECTIONS-213. Added multiple use support to IteratorIterable.
Modified:
commons/proper/collections/trunk/src/java/org/apache/commons/collections/IteratorUtils.java
commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/IteratorIterable.java
commons/proper/collections/trunk/src/test/org/apache/commons/collections/TestIteratorUtils.java
commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestIteratorIterable.java
Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/IteratorUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/IteratorUtils.java?rev=1127604&r1=1127603&r2=1127604&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/IteratorUtils.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/IteratorUtils.java Wed May 25 18:04:29 2011
@@ -759,7 +759,8 @@ public class IteratorUtils {
}
/**
- * Gets an iterable that wraps an iterator.
+ * Gets an iterable that wraps an iterator. The returned iterable can be
+ * used for a single iteration.
*
* @param iterator the iterator to use, not null
* @return a new, single use iterable
@@ -769,7 +770,22 @@ public class IteratorUtils {
if (iterator == null) {
throw new NullPointerException("Iterator must not be null");
}
- return new IteratorIterable<E>(iterator);
+ return new IteratorIterable<E>(iterator, false);
+ }
+
+ /**
+ * Gets an iterable that wraps an iterator. The returned iterable can be
+ * used for multiple iterations.
+ *
+ * @param iterator the iterator to use, not null
+ * @return a new, multiple use iterable
+ * @throws NullPointerException if iterator is null
+ */
+ public static <E> Iterable<E> asMultipleUseIterable(Iterator<? extends E> iterator) {
+ if (iterator == null) {
+ throw new NullPointerException("Iterator must not be null");
+ }
+ return new IteratorIterable<E>(iterator, true);
}
/**
Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/IteratorIterable.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/IteratorIterable.java?rev=1127604&r1=1127603&r2=1127604&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/IteratorIterable.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/IteratorIterable.java Wed May 25 18:04:29 2011
@@ -15,11 +15,47 @@ package org.apache.commons.collections.i
import java.util.Iterator;
+import org.apache.commons.collections.ResettableIterator;
+
/**
* Adapter to make an {@link Iterator Iterator} instance appear to be an
- * {@link Iterable Iterable} instance. Unlike normal iterable instance, the
- * {@link #iterator()} method always returns the same iterator instance. This
- * prohibits this iterator to be only usable for one iterative operation.
+ * {@link Iterable Iterable} instance. The iterable can be constructed in one
+ * of two variants: single use, multiple use.
+ *
+ * <p>
+ * In the single use iterable case, the iterable is only usable for one
+ * iterative operation over the source iterator. Subsequent iterative
+ * operations use the same, exhausted source iterator. To create a single use
+ * iterable, construct a new {@link IteratorIterable} using a {@link Iterator}
+ * that is NOT a {@link ResettableIterator} iterator:
+ * <pre>
+ * Iterator<Integer> iterator = // some non-resettable iterator
+ * Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator);
+ * </pre>
+ * </p>
+ *
+ * <p>
+ * In the multiple use iterable case, the iterable is usable for any number of
+ * iterative operations over the source iterator. Of special note, even though
+ * the iterable supports multiple iterations, it does not support concurrent
+ * iterations. To implicitly create a multiple use iterable, construct a new
+ * {@link IteratorIterable} using a {@link ResettableIterator} iterator:
+ * <pre>
+ * Integer[] array = {Integer.valueOf(1),Integer.valueOf(2),Integer.valueOf(3)};
+ * Iterator<Integer> iterator = IteratorUtils.arrayIterator(array); // a resettable iterator
+ * Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator);
+ * </pre>
+ * </p>
+ *
+ * <p>
+ * A multiple use iterable can also be explicitly constructed using any
+ * {@link Iterator} and specifying <code>true</code> for the
+ * <code>multipleUse</code> flag:
+ * <pre>
+ * Iterator<Integer> iterator = // some non-resettable iterator
+ * Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator, true);
+ * </pre>
+ * </p>
*
* @since Commons Collections 4.0
* @version $Revision: $ $Date: $
@@ -47,9 +83,12 @@ public class IteratorIterable<E> impleme
};
}
- /** the iterator being used. */
- private final Iterator<E> iterator;
-
+ /** the iterator being adapted into an iterable. */
+ private final Iterator<? extends E> iterator;
+
+ /** the iterator parameterized as the {@link #iterator()} return type. */
+ private final Iterator<E> typeSafeIterator;
+
/**
* Constructs a new <code>IteratorIterable</code> that will use the given
* iterator.
@@ -57,8 +96,24 @@ public class IteratorIterable<E> impleme
* @param iterator the iterator to use.
*/
public IteratorIterable(Iterator<? extends E> iterator) {
+ this(iterator, false);
+ }
+
+ /**
+ * Constructs a new <code>IteratorIterable</code> that will use the given
+ * iterator.
+ *
+ * @param iterator the iterator to use.
+ * @param multipleUse <code>true</code> if the new iterable can be used in multiple iterations
+ */
+ public IteratorIterable(Iterator<? extends E> iterator, boolean multipleUse) {
super();
- this.iterator = createTypesafeIterator(iterator);
+ if (multipleUse && !(iterator instanceof ResettableIterator)) {
+ this.iterator = new ListIteratorWrapper<E>(iterator);
+ } else {
+ this.iterator = iterator;
+ }
+ this.typeSafeIterator = createTypesafeIterator(this.iterator);
}
/**
@@ -67,6 +122,9 @@ public class IteratorIterable<E> impleme
* @return the iterator
*/
public Iterator<E> iterator() {
- return iterator;
+ if (iterator instanceof ResettableIterator) {
+ ((ResettableIterator<? extends E>)iterator).reset();
+ }
+ return typeSafeIterator;
}
}
Modified: commons/proper/collections/trunk/src/test/org/apache/commons/collections/TestIteratorUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/org/apache/commons/collections/TestIteratorUtils.java?rev=1127604&r1=1127603&r2=1127604&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/test/org/apache/commons/collections/TestIteratorUtils.java (original)
+++ commons/proper/collections/trunk/src/test/org/apache/commons/collections/TestIteratorUtils.java Wed May 25 18:04:29 2011
@@ -61,6 +61,8 @@ public class TestIteratorUtils extends B
assertEquals(expected, actual.intValue());
++expected;
}
+ // insure iteration occurred
+ assertTrue(expected > 0);
// single use iterator
for(Integer actual : iterable) {
@@ -76,6 +78,41 @@ public class TestIteratorUtils extends B
// success
}
}
+
+ public void testAsMultipleIterable() {
+ List<Integer> list = new ArrayList<Integer>();
+ list.add(Integer.valueOf(0));
+ list.add(Integer.valueOf(1));
+ list.add(Integer.valueOf(2));
+ Iterator<Integer> iterator = list.iterator();
+
+ Iterable<Integer> iterable = IteratorUtils.asMultipleUseIterable(iterator);
+ int expected = 0;
+ for(Integer actual : iterable) {
+ assertEquals(expected, actual.intValue());
+ ++expected;
+ }
+ // insure iteration occurred
+ assertTrue(expected > 0);
+
+ // multiple use iterator
+ expected = 0;
+ for(Integer actual : iterable) {
+ assertEquals(expected, actual.intValue());
+ ++expected;
+ }
+ // insure iteration occurred
+ assertTrue(expected > 0);
+ }
+
+ public void testAsMultipleIterableNull() {
+ try {
+ IteratorUtils.asMultipleUseIterable(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // success
+ }
+ }
public void testToList() {
List<Object> list = new ArrayList<Object>();
Modified: commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestIteratorIterable.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestIteratorIterable.java?rev=1127604&r1=1127603&r2=1127604&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestIteratorIterable.java (original)
+++ commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestIteratorIterable.java Wed May 25 18:04:29 2011
@@ -36,19 +36,47 @@ public class TestIteratorIterable extend
super(name);
}
- public void testIterator() {
+ private Iterator<Integer> createIterator() {
List<Integer> list = new ArrayList<Integer>();
list.add(Integer.valueOf(0));
list.add(Integer.valueOf(1));
list.add(Integer.valueOf(2));
Iterator<Integer> iter = list.iterator();
+ return iter;
+ }
+ public void testIterator() {
+ Iterator<Integer> iter = createIterator();
Iterable<Number> iterable = new IteratorIterable<Number>(iter);
+
+ // first use
+ verifyIteration(iterable);
+
+ // second use
+ for (Number actual : iterable) {
+ fail("should not be able to iterate twice");
+ }
+ }
+
+ public void testMultipleUserIterator() {
+ Iterator<Integer> iter = createIterator();
+
+ Iterable<Number> iterable = new IteratorIterable<Number>(iter, true);
+
+ // first use
+ verifyIteration(iterable);
+
+ // second use
+ verifyIteration(iterable);
+ }
+
+ private void verifyIteration(Iterable<Number> iterable) {
int expected = 0;
for (Number actual : iterable) {
assertEquals(expected, actual.intValue());
++expected;
}
+ assertTrue(expected > 0);
}
}