You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ba...@apache.org on 2009/09/15 07:55:31 UTC
svn commit: r815060 -
/commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ListIteratorWrapper.java
Author: bayard
Date: Tue Sep 15 05:55:31 2009
New Revision: 815060
URL: http://svn.apache.org/viewvc?rev=815060&view=rev
Log:
Merging from -r468106:814127 of collections_jdk5_branch - namely where this code was generified; mostly in r738956.
Also see the following revisions:
------------------------------------------------------------------------
r751857 | mbenson | 2009-03-09 14:43:53 -0700 (Mon, 09 Mar 2009) | 1 line
handle more ListIterator functionality when possible
------------------------------------------------------------------------
Modified:
commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ListIteratorWrapper.java
Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ListIteratorWrapper.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ListIteratorWrapper.java?rev=815060&r1=815059&r2=815060&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ListIteratorWrapper.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ListIteratorWrapper.java Tue Sep 15 05:55:31 2009
@@ -16,15 +16,21 @@
*/
package org.apache.commons.collections.iterators;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.ListIterator;
import java.util.NoSuchElementException;
+import org.apache.commons.collections.ResettableIterator;
import org.apache.commons.collections.ResettableListIterator;
/**
- * Converts an iterator into a list iterator by caching the returned entries.
+ * Converts an {@link Iterator} into a {@link ResettableListIterator}.
+ * For plain <code>Iterator</code>s this is accomplished by caching the returned
+ * elements. This class can also be used to simply add {@link ResettableIterator}
+ * functionality to a given {@link ListIterator}.
* <p>
* The <code>ListIterator</code> interface has additional useful methods
* for navigation - <code>previous()</code> and the index methods.
@@ -32,7 +38,7 @@
* <code>ListIterator</code>. It achieves this by building a list internally
* of as the underlying iterator is traversed.
* <p>
- * The optional operations of <code>ListIterator</code> are not supported.
+ * The optional operations of <code>ListIterator</code> are not supported for plain <code>Iterator</code>s.
* <p>
* This class implements ResettableListIterator from Commons Collections 3.2.
*
@@ -41,22 +47,28 @@
*
* @author Morgan Delagrange
* @author Stephen Colebourne
+ * @author Matt Benson
*/
-public class ListIteratorWrapper implements ResettableListIterator {
+public class ListIteratorWrapper<E> implements ResettableListIterator<E> {
- /** Message used when remove, set or add are called. */
+ /** Message used when set or add are called. */
private static final String UNSUPPORTED_OPERATION_MESSAGE =
"ListIteratorWrapper does not support optional operations of ListIterator.";
+ /** Message used when set or add are called. */
+ private static final String CANNOT_REMOVE_MESSAGE = "Cannot remove element at index {0}.";
+
/** The underlying iterator being decorated. */
- private final Iterator iterator;
+ private final Iterator<? extends E> iterator;
/** The list being used to cache the iterator. */
- private final List list = new ArrayList();
+ private final List<E> list = new ArrayList<E>();
/** The current index of this iterator. */
private int currentIndex = 0;
/** The current index of the wrapped iterator. */
private int wrappedIteratorIndex = 0;
+ /** recall whether the wrapped iterator's "cursor" is in such a state as to allow remove() to be called */
+ private boolean removeState;
// Constructor
//-------------------------------------------------------------------------
@@ -67,7 +79,7 @@
* @param iterator the iterator to wrap
* @throws NullPointerException if the iterator is null
*/
- public ListIteratorWrapper(Iterator iterator) {
+ public ListIteratorWrapper(Iterator<? extends E> iterator) {
super();
if (iterator == null) {
throw new NullPointerException("Iterator must not be null");
@@ -78,12 +90,19 @@
// ListIterator interface
//-------------------------------------------------------------------------
/**
- * Throws {@link UnsupportedOperationException}.
+ * Throws {@link UnsupportedOperationException}
+ * unless the underlying <code>Iterator</code> is a <code>ListIterator</code>.
*
- * @param obj the object to add, ignored
- * @throws UnsupportedOperationException always
+ * @param obj the object to add
+ * @throws UnsupportedOperationException
*/
- public void add(Object obj) throws UnsupportedOperationException {
+ public void add(E obj) throws UnsupportedOperationException {
+ if (iterator instanceof ListIterator) {
+ @SuppressWarnings("unchecked")
+ ListIterator<E> li = (ListIterator<E>) iterator;
+ li.add(obj);
+ return;
+ }
throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_MESSAGE);
}
@@ -93,7 +112,7 @@
* @return true if there are more elements
*/
public boolean hasNext() {
- if (currentIndex == wrappedIteratorIndex) {
+ if (currentIndex == wrappedIteratorIndex || iterator instanceof ListIterator) {
return iterator.hasNext();
}
return true;
@@ -105,10 +124,12 @@
* @return true if there are previous elements
*/
public boolean hasPrevious() {
- if (currentIndex == 0) {
- return false;
+ if (iterator instanceof ListIterator) {
+ @SuppressWarnings("unchecked")
+ ListIterator li = (ListIterator) iterator;
+ return li.hasPrevious();
}
- return true;
+ return currentIndex > 0;
}
/**
@@ -117,25 +138,35 @@
* @return the next element from the iterator
* @throws NoSuchElementException if there are no more elements
*/
- public Object next() throws NoSuchElementException {
+ public E next() throws NoSuchElementException {
+ if (iterator instanceof ListIterator) {
+ return iterator.next();
+ }
+
if (currentIndex < wrappedIteratorIndex) {
++currentIndex;
return list.get(currentIndex - 1);
}
- Object retval = iterator.next();
+ E retval = iterator.next();
list.add(retval);
++currentIndex;
++wrappedIteratorIndex;
+ removeState = true;
return retval;
}
/**
- * Returns in the index of the next element.
+ * Returns the index of the next element.
*
* @return the index of the next element
*/
public int nextIndex() {
+ if (iterator instanceof ListIterator) {
+ @SuppressWarnings("unchecked")
+ ListIterator li = (ListIterator) iterator;
+ return li.nextIndex();
+ }
return currentIndex;
}
@@ -145,12 +176,18 @@
* @return the previous element
* @throws NoSuchElementException if there are no previous elements
*/
- public Object previous() throws NoSuchElementException {
+ public E previous() throws NoSuchElementException {
+ if (iterator instanceof ListIterator) {
+ @SuppressWarnings("unchecked")
+ ListIterator<E> li = (ListIterator<E>) iterator;
+ return li.previous();
+ }
+
if (currentIndex == 0) {
throw new NoSuchElementException();
}
- --currentIndex;
- return list.get(currentIndex);
+ removeState = wrappedIteratorIndex == currentIndex;
+ return list.get(--currentIndex);
}
/**
@@ -159,25 +196,52 @@
* @return the index of the previous element
*/
public int previousIndex() {
+ if (iterator instanceof ListIterator) {
+ @SuppressWarnings("unchecked")
+ ListIterator li = (ListIterator) iterator;
+ return li.previousIndex();
+ }
return currentIndex - 1;
}
/**
- * Throws {@link UnsupportedOperationException}.
+ * Throws {@link UnsupportedOperationException} if {@link #previous()} has ever been called.
*
* @throws UnsupportedOperationException always
*/
public void remove() throws UnsupportedOperationException {
- throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_MESSAGE);
+ if (iterator instanceof ListIterator) {
+ iterator.remove();
+ return;
+ }
+ int removeIndex = currentIndex;
+ if (currentIndex == wrappedIteratorIndex) {
+ --removeIndex;
+ }
+ if (!removeState || wrappedIteratorIndex - currentIndex > 1) {
+ throw new IllegalStateException(MessageFormat.format(CANNOT_REMOVE_MESSAGE, removeIndex));
+ }
+ iterator.remove();
+ list.remove(removeIndex);
+ currentIndex = removeIndex;
+ wrappedIteratorIndex--;
+ removeState = false;
}
/**
- * Throws {@link UnsupportedOperationException}.
- *
- * @param obj the object to set, ignored
- * @throws UnsupportedOperationException always
- */
- public void set(Object obj) throws UnsupportedOperationException {
+ * Throws {@link UnsupportedOperationException}
+ * unless the underlying <code>Iterator</code> is a <code>ListIterator</code>.
+ *
+ * @param obj the object to set
+ * @throws UnsupportedOperationException
+ */
+ public void set(E obj) throws UnsupportedOperationException {
+ if (iterator instanceof ListIterator) {
+ @SuppressWarnings("unchecked")
+ ListIterator<E> li = (ListIterator<E>) iterator;
+ li.set(obj);
+ return;
+ }
throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_MESSAGE);
}
@@ -190,6 +254,14 @@
* @since Commons Collections 3.2
*/
public void reset() {
+ if (iterator instanceof ListIterator) {
+ @SuppressWarnings("unchecked")
+ ListIterator li = (ListIterator) iterator;
+ while (li.previousIndex() >= 0) {
+ li.previous();
+ }
+ return;
+ }
currentIndex = 0;
}