diff --git a/src/java/org/apache/commons/collections/FilterListIterator.java b/src/java/org/apache/commons/collections/FilterListIterator.java
index 58247f3f2..eb5268d9b 100644
--- a/src/java/org/apache/commons/collections/FilterListIterator.java
+++ b/src/java/org/apache/commons/collections/FilterListIterator.java
@@ -1,7 +1,7 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/Attic/FilterListIterator.java,v 1.1 2002/02/25 23:53:20 rwaldhoff Exp $
- * $Revision: 1.1 $
- * $Date: 2002/02/25 23:53:20 $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/Attic/FilterListIterator.java,v 1.2 2002/02/26 17:28:55 rwaldhoff Exp $
+ * $Revision: 1.2 $
+ * $Date: 2002/02/26 17:28:55 $
*
* ====================================================================
*
@@ -64,19 +64,21 @@ import java.util.ListIterator;
import java.util.NoSuchElementException;
/**
- * A proxy {@link ListIterator ListIterator} which takes a {@link Predicate Predicate} instance to filter
- * out objects from an underlying {@link Iterator Iterator} instance.
- * Only objects for which the
- * specified Predicate
evaluates to true
are
- * returned.
- *
- * @author James Strachan
- * @author Jan Sorensen
+ * A proxy {@link ListIterator ListIterator} which
+ * takes a {@link Predicate Predicate} instance to filter
+ * out objects from an underlying ListIterator
+ * instance. Only objects for which the specified
+ * Predicate
evaluates to true
are
+ * returned by the iterator.
+ *
+ * @version $Revision: 1.2 $ $Date: 2002/02/26 17:28:55 $
+ * @author Rodney Waldhoff
*/
-
public class FilterListIterator extends ProxyListIterator {
+ // Constructors
//-------------------------------------------------------------------------
+
public FilterListIterator() {
}
@@ -89,9 +91,14 @@ public class FilterListIterator extends ProxyListIterator {
this.predicate = predicate;
}
+ public FilterListIterator(Predicate predicate) {
+ this.predicate = predicate;
+ }
+
// ListIterator interface
//-------------------------------------------------------------------------
+ /** Not supported. */
public void add(Object o) {
throw new UnsupportedOperationException("FilterListIterator.add(Object) is not supported.");
}
@@ -118,9 +125,10 @@ public class FilterListIterator extends ProxyListIterator {
throw new NoSuchElementException();
}
}
- nextObjectSet = false;
nextIndex++;
- return nextObject;
+ Object temp = nextObject;
+ clearNextObject();
+ return temp;
}
public int nextIndex() {
@@ -133,19 +141,22 @@ public class FilterListIterator extends ProxyListIterator {
throw new NoSuchElementException();
}
}
- previousObjectSet = false;
nextIndex--;
- return previousObject;
+ Object temp = previousObject;
+ clearPreviousObject();
+ return temp;
}
public int previousIndex() {
return (nextIndex-1);
}
+ /** Not supported. */
public void remove() {
throw new UnsupportedOperationException("FilterListIterator.remove() is not supported.");
}
+ /** Not supported. */
public void set(Object o) {
throw new UnsupportedOperationException("FilterListIterator.set(Object) is not supported.");
}
@@ -168,14 +179,29 @@ public class FilterListIterator extends ProxyListIterator {
this.predicate = predicate;
}
- /**
- * Set {@link #nextObject} to the next object. If there
- * are no more objects then return false
.
- * Otherwise, return true
.
- */
+ // Private Methods
+ //-------------------------------------------------------------------------
+
+ private void clearNextObject() {
+ nextObject = null;
+ nextObjectSet = false;
+ }
+
private boolean setNextObject() {
ListIterator iterator = getListIterator();
Predicate predicate = getPredicate();
+
+ // if previousObjectSet,
+ // then we've walked back one step in the
+ // underlying list (due to a hasPrevious() call)
+ // so skip ahead one matching object
+ if(previousObjectSet) {
+ clearPreviousObject();
+ if(!setNextObject()) {
+ return false;
+ }
+ }
+
while(iterator.hasNext()) {
Object object = iterator.next();
if(predicate.evaluate(object)) {
@@ -187,14 +213,26 @@ public class FilterListIterator extends ProxyListIterator {
return false;
}
- /**
- * Set {@link #nextObject} to the next object. If there
- * are no more objects then return false
.
- * Otherwise, return true
.
- */
+ private void clearPreviousObject() {
+ previousObject = null;
+ previousObjectSet = false;
+ }
+
private boolean setPreviousObject() {
ListIterator iterator = getListIterator();
Predicate predicate = getPredicate();
+
+ // if nextObjectSet,
+ // then we've walked back one step in the
+ // underlying list (due to a hasNext() call)
+ // so skip ahead one matching object
+ if(nextObjectSet) {
+ clearNextObject();
+ if(!setPreviousObject()) {
+ return false;
+ }
+ }
+
while(iterator.hasPrevious()) {
Object object = iterator.previous();
if(predicate.evaluate(object)) {
@@ -224,7 +262,6 @@ public class FilterListIterator extends ProxyListIterator {
*/
private boolean nextObjectSet = false;
-
/**
* The value of the previous (matching) object, when
* {@link #previousObjectSet} is true.
diff --git a/src/test/org/apache/commons/collections/TestFilterListIterator.java b/src/test/org/apache/commons/collections/TestFilterListIterator.java
index 6c9e73db4..522a585f3 100644
--- a/src/test/org/apache/commons/collections/TestFilterListIterator.java
+++ b/src/test/org/apache/commons/collections/TestFilterListIterator.java
@@ -1,7 +1,7 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/Attic/TestFilterListIterator.java,v 1.1 2002/02/25 23:53:20 rwaldhoff Exp $
- * $Revision: 1.1 $
- * $Date: 2002/02/25 23:53:20 $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/Attic/TestFilterListIterator.java,v 1.2 2002/02/26 17:28:55 rwaldhoff Exp $
+ * $Revision: 1.2 $
+ * $Date: 2002/02/26 17:28:55 $
*
* ====================================================================
*
@@ -70,7 +70,7 @@ import java.util.ListIterator;
import java.util.Random;
/**
- * @version $Revision: 1.1 $ $Date: 2002/02/25 23:53:20 $
+ * @version $Revision: 1.2 $ $Date: 2002/02/26 17:28:55 $
* @author Rodney Waldhoff
*/
public class TestFilterListIterator extends TestCase {
@@ -112,6 +112,7 @@ public class TestFilterListIterator extends TestCase {
list.add(new Integer(i));
if(i%2 == 0) { evens.add(new Integer(i)); }
if(i%2 == 1) { odds.add(new Integer(i)); }
+ if(i%3 == 0) { threes.add(new Integer(i)); }
if(i%4 == 0) { fours.add(new Integer(i)); }
if(i%6 == 0) { sixes.add(new Integer(i)); }
}
@@ -238,7 +239,7 @@ public class TestFilterListIterator extends TestCase {
FilterListIterator filtered = new FilterListIterator(list.listIterator(),truePred);
walkLists(list,filtered);
}
-
+
public void testFalsePredicate() {
FilterListIterator filtered = new FilterListIterator(list.listIterator(),falsePred);
walkLists(new ArrayList(),filtered);
@@ -280,26 +281,98 @@ public class TestFilterListIterator extends TestCase {
walkLists(sixes,filtered);
}
+ public void testNestedSixes3() {
+ FilterListIterator filtered = new FilterListIterator(
+ new FilterListIterator(list.listIterator(),threePred),
+ evenPred
+ );
+ walkLists(sixes,new FilterListIterator(filtered,truePred));
+ }
+
+ public void testNextChangesPrevious() {
+ {
+ FilterListIterator filtered = new FilterListIterator(list.listIterator(),threePred);
+ nextNextPrevious(threes.listIterator(),filtered);
+ }
+
+ {
+ FilterListIterator filtered = new FilterListIterator(list.listIterator(),truePred);
+ nextNextPrevious(list.listIterator(),filtered);
+ }
+ }
+
+ public void testPreviousChangesNext() {
+ {
+ FilterListIterator filtered = new FilterListIterator(list.listIterator(),threePred);
+ ListIterator expected = threes.listIterator();
+ walkForward(expected,filtered);
+ previousPreviousNext(expected,filtered);
+ }
+ {
+ FilterListIterator filtered = new FilterListIterator(list.listIterator(),truePred);
+ ListIterator expected = list.listIterator();
+ walkForward(expected,filtered);
+ previousPreviousNext(expected,filtered);
+ }
+ }
+
// Utilities
+ private void walkForward(ListIterator expected, ListIterator testing) {
+ while(expected.hasNext()) {
+ assertEquals(expected.nextIndex(),testing.nextIndex());
+ assertEquals(expected.previousIndex(),testing.previousIndex());
+ assertTrue(testing.hasNext());
+ assertEquals(expected.next(),testing.next());
+ }
+ }
+
+ private void walkBackward(ListIterator expected, ListIterator testing) {
+ while(expected.hasPrevious()) {
+ assertEquals(expected.nextIndex(),testing.nextIndex());
+ assertEquals(expected.previousIndex(),testing.previousIndex());
+ assertTrue(testing.hasPrevious());
+ assertEquals(expected.previous(),testing.previous());
+ }
+ }
+
+ private void nextNextPrevious(ListIterator expected, ListIterator testing) {
+ // calls to next() should change the value returned by previous()
+ // even after previous() has been set by a call to hasPrevious()
+ assertEquals(expected.next(),testing.next());
+ assertEquals(expected.hasPrevious(),testing.hasPrevious());
+ Object expecteda = expected.next();
+ Object testinga = testing.next();
+ assertEquals(expecteda,testinga);
+ Object expectedb = expected.previous();
+ Object testingb = testing.previous();
+ assertEquals(expecteda,expectedb);
+ assertEquals(testinga,testingb);
+ }
+
+ private void previousPreviousNext(ListIterator expected, ListIterator testing) {
+ // calls to previous() should change the value returned by next()
+ // even after next() has been set by a call to hasNext()
+ assertEquals(expected.previous(),testing.previous());
+ assertEquals(expected.hasNext(),testing.hasNext());
+ Object expecteda = expected.previous();
+ Object testinga = testing.previous();
+ assertEquals(expecteda,testinga);
+ Object expectedb = expected.next();
+ Object testingb = testing.next();
+ assertEquals(expecteda,testingb);
+ assertEquals(expecteda,expectedb);
+ assertEquals(testinga,testingb);
+ }
+
private void walkLists(List list, ListIterator testing) {
ListIterator expected = list.listIterator();
// walk all the way forward
- while(expected.hasNext()) {
- assertEquals(expected.nextIndex(),testing.nextIndex());
- assertEquals(expected.previousIndex(),testing.previousIndex());
- assertTrue("a",testing.hasNext());
- assertEquals("b",expected.next(),testing.next());
- }
-
+ walkForward(expected,testing);
+
// walk all the way back
- while(expected.hasPrevious()) {
- assertEquals(expected.nextIndex(),testing.nextIndex());
- assertEquals(expected.previousIndex(),testing.previousIndex());
- assertTrue("c",testing.hasPrevious());
- assertEquals("d",expected.previous(),testing.previous());
- }
+ walkBackward(expected,testing);
// forward,back,foward
while(expected.hasNext()) {
@@ -313,13 +386,9 @@ public class TestFilterListIterator extends TestCase {
assertEquals(expected.next(),testing.next());
}
+
// walk all the way back
- while(expected.hasPrevious()) {
- assertEquals(expected.nextIndex(),testing.nextIndex());
- assertEquals(expected.previousIndex(),testing.previousIndex());
- assertTrue(testing.hasPrevious());
- assertEquals(expected.previous(),testing.previous());
- }
+ walkBackward(expected,testing);
for(int i=0;i