diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 772480127..b91313713 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -126,6 +126,9 @@ Changed classes / methods
-------------------------
o [COLLECTIONS-466] Replaced "Collection" with "Iterable" for method arguments where applicable.
+ o [COLLECTIONS-460] Changed "IteratorChain" to use internally a "Queue" instead of a "List". Iterators are
+ removed from the queue once used and can be garbage collected after being exhausted.
+ Additionally removed the methods "setIterator(Iterator)" and "getIterators()".
o [COLLECTIONS-454] An iterator over a "Flat3Map#entrySet()" will now return independent Map.Entry objects that will
not change anymore when the iterator progresses.
o [COLLECTIONS-453] Several closure and transformer implementations in the functor package will now copy
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 5b390527c..d4ceda5c6 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -31,6 +31,11 @@
Added "PeekingIterator" decorator to support one-element lookahead during iteration.
+
+ Changed "IteratorChain" to use internally a "Queue" instead of a "List". Iterators are
+ removed from the queue once used and can be garbage collected after being exhausted.
+ Additionally removed the methods "setIterator(Iterator)" and "getIterators()".
+
Removed unused class "AbstractUntypedCollectionDecorator<E, D>".
diff --git a/src/main/java/org/apache/commons/collections4/iterators/IteratorChain.java b/src/main/java/org/apache/commons/collections4/iterators/IteratorChain.java
index 676184522..c703f07c6 100644
--- a/src/main/java/org/apache/commons/collections4/iterators/IteratorChain.java
+++ b/src/main/java/org/apache/commons/collections4/iterators/IteratorChain.java
@@ -16,12 +16,10 @@
*/
package org.apache.commons.collections4.iterators;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
-import java.util.List;
-
-import org.apache.commons.collections4.list.UnmodifiableList;
+import java.util.LinkedList;
+import java.util.Queue;
/**
* An IteratorChain is an Iterator that wraps a number of Iterators.
@@ -37,10 +35,15 @@ import org.apache.commons.collections4.list.UnmodifiableList;
*
* Calling a method that adds new Iterator after a method in the Iterator
* interface has been called will result in an UnsupportedOperationException.
- * Subclasses should take care to not alter the underlying List of Iterators.
*
* NOTE: As from version 3.0, the IteratorChain may contain no iterators. In
* this case the class will function as an empty iterator.
+ *
+ * NOTE: As from version 4.0, the IteratorChain stores the iterators in a queue
+ * and removes any reference to them as soon as they are not used anymore. Thus
+ * the methods {@code setIterator(Iterator)} and {@code getIterators()} have been
+ * removed and {@link #size()} will return the number of remaining iterators in
+ * the queue.
*
* @since 2.1
* @version $Id$
@@ -48,10 +51,7 @@ import org.apache.commons.collections4.list.UnmodifiableList;
public class IteratorChain implements Iterator {
/** The chain of iterators */
- private final List> iteratorChain = new ArrayList>();
-
- /** The index of the current iterator */
- private int currentIteratorIndex = 0;
+ private final Queue> iteratorChain = new LinkedList>();
/** The current iterator */
private Iterator extends E> currentIterator = null;
@@ -165,34 +165,7 @@ public class IteratorChain implements Iterator {
}
/**
- * Set the Iterator at the given index
- *
- * @param index index of the Iterator to replace
- * @param iterator Iterator to place at the given index
- * @throws IndexOutOfBoundsException if index < 0 or index > size()
- * @throws IllegalStateException if I've already started iterating
- * @throws NullPointerException if the iterator is null
- */
- public void setIterator(final int index, final Iterator extends E> iterator)
- throws IndexOutOfBoundsException {
- checkLocked();
- if (iterator == null) {
- throw new NullPointerException("Iterator must not be null");
- }
- iteratorChain.set(index, iterator);
- }
-
- /**
- * Get the list of Iterators (unmodifiable)
- *
- * @return the unmodifiable list of iterators added
- */
- public List> getIterators() {
- return UnmodifiableList.unmodifiableList(iteratorChain);
- }
-
- /**
- * Number of Iterators in the current IteratorChain.
+ * Returns the remaining number of Iterators in the current IteratorChain.
*
* @return Iterator count
*/
@@ -240,17 +213,15 @@ public class IteratorChain implements Iterator {
if (iteratorChain.isEmpty()) {
currentIterator = EmptyIterator. emptyIterator();
} else {
- currentIterator = iteratorChain.get(0);
+ currentIterator = iteratorChain.remove();
}
// set last used iterator here, in case the user calls remove
// before calling hasNext() or next() (although they shouldn't)
lastUsedIterator = currentIterator;
}
- while (currentIterator.hasNext() == false
- && currentIteratorIndex < iteratorChain.size() - 1) {
- currentIteratorIndex++;
- currentIterator = iteratorChain.get(currentIteratorIndex);
+ while (currentIterator.hasNext() == false && !iteratorChain.isEmpty()) {
+ currentIterator = iteratorChain.remove();
}
}