org.apache.commons.collections.FilterIterator implements the Iterator
interface. But the Iterator is advanced with the hasNext() method, and not
with the next(). That means that it relies on being used with alternate
calls to hasNext() and next(), like:
while (iter.hasNext()) { .... iter.next(); ... }
Multiple calls to next() would return the same element, and calls to
hasNext() skip over elements.
This patch fix this, and also makes the remove() throw an
UnsupportedOperationException. The underlying iterator might not be in sync
with the FilterIterator so remove() is a bit hard to implement.
--
Jan Sorensen
aragost
Index: FilterIterator.java
===================================================================
RCS file:
/home/cvspublic/jakarta-commons/collections/src/java/org/apache/commons/coll
ections/FilterIterator.java,v
retrieving revision 1.1
diff -u -r1.1 FilterIterator.java
--- FilterIterator.java 2001/05/06 11:04:25 1.1
+++ FilterIterator.java 2001/09/03 07:48:13
@@ -7,8 +7,8 @@
*/
package org.apache.commons.collections;
-import java.util.Enumeration;
import java.util.Iterator;
+import java.util.NoSuchElementException;
/** A Proxy {@link Iterator Iterator} which takes a {@link Predicate
Predicate} instance to filter
* out objects from an underlying {@link Iterator Iterator} instance.
@@ -20,7 +20,9 @@
/** Holds value of property predicate. */
private Predicate predicate;
+
private Object nextObject;
+ private boolean nextObjectSet = false;
//-------------------------------------------------------------------------
@@ -39,20 +41,44 @@
// Iterator interface
//-------------------------------------------------------------------------
public boolean hasNext() {
+ if (nextObjectSet)
+ return true;
+ else
+ return setNextObject();
+ }
+
+ public Object next() {
+ if (!nextObjectSet)
+ if (!setNextObject())
+ throw new NoSuchElementException();
+ nextObjectSet = false;
+ return nextObject;
+ }
+
+ public void remove() {
+ /* The unlying iterator might not be in sync, so we can't forward
+ * the call.
+ */
+ throw new UnsupportedOperationException();
+ }
+
+ // Private methods
+
//-------------------------------------------------------------------------
+ /** Set nextObject to the next object. If there is no more objects,
return
+ * false, otherwise return true
+ */
+ private boolean setNextObject() {
Iterator iterator = getIterator();
Predicate predicate = getPredicate();
while ( iterator.hasNext() ) {
Object object = iterator.next();
if ( predicate.evaluate( object ) ) {
nextObject = object;
+ nextObjectSet = true;
return true;
}
}
return false;
- }
-
- public Object next() {
- return nextObject;
}
// Properties