You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2006/05/06 18:10:32 UTC
svn commit: r400329 - in /jakarta/commons/proper/collections/trunk: ./
src/java/org/apache/commons/collections/iterators/
src/test/org/apache/commons/collections/iterators/
Author: scolebourne
Date: Sat May 6 09:10:31 2006
New Revision: 400329
URL: http://svn.apache.org/viewcvs?rev=400329&view=rev
Log:
Add ReverseListIterator
rfe 39224, including code from Serge Knystautas
Added:
jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ReverseListIterator.java (with props)
jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestReverseListIterator.java (with props)
Modified:
jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html
jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestAll.java
Modified: jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html?rev=400329&r1=400328&r2=400329&view=diff
==============================================================================
--- jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html (original)
+++ jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html Sat May 6 09:10:31 2006
@@ -58,6 +58,7 @@
<li>DefaultedMap - Returns a default value when the key is not found, without adding the default value to the map itself [30911]</li>
<li>GrowthList - Decorator that causes set and indexed add to expand the list rather than throw IndexOutOfBoundsException [34171]</li>
<li>LoopingListIterator - When the end of the list is reached the iteration continues from the start [30166]</li>
+<li>ReverseListIterator - A list iterator that returns the elements from the list in reverse order [39224]</li>
<li>BoundedBuffer - A new wrapper class which can make any buffer bounded [37473]</li>
</ul>
Added: jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ReverseListIterator.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ReverseListIterator.java?rev=400329&view=auto
==============================================================================
--- jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ReverseListIterator.java (added)
+++ jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ReverseListIterator.java Sat May 6 09:10:31 2006
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections.iterators;
+
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.commons.collections.ResettableListIterator;
+
+/**
+ * Iterates backwards through a List, starting with the last element
+ * and continuing to the first. This is useful for looping around
+ * a list in reverse order without needing to actually reverse the list.
+ * <p>
+ * The first call to <code>next()</code> will return the last element
+ * from the list, and so on. The <code>hasNext()</code> method works
+ * in concert with the <code>next()</code> method as expected.
+ * However, the <code>nextIndex()</code> method returns the correct
+ * index in the list, thus it starts high and reduces as the iteration
+ * continues. The previous methods work similarly.
+ *
+ * @author Serge Knystautas
+ * @author Stephen Colebourne
+ * @version $Revision: $ $Date$
+ */
+public class ReverseListIterator implements ResettableListIterator {
+
+ /** The list being wrapped. */
+ private final List list;
+ /** The list iterator being wrapped. */
+ private ListIterator iterator;
+ /** Flag to indicate if updating is possible at the moment. */
+ private boolean validForUpdate = true;
+
+ /**
+ * Constructor that wraps a list.
+ *
+ * @param list the list to create a reversed iterator for
+ * @throws NullPointerException if the list is null
+ */
+ public ReverseListIterator(List list) {
+ super();
+ this.list = list;
+ iterator = list.listIterator(list.size());
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks whether there is another element.
+ *
+ * @return true if there is another element
+ */
+ public boolean hasNext() {
+ return iterator.hasPrevious();
+ }
+
+ /**
+ * Gets the next element.
+ * The next element is the previous in the list.
+ *
+ * @return the next element in the iterator
+ */
+ public Object next() {
+ Object obj = iterator.previous();
+ validForUpdate = true;
+ return obj;
+ }
+
+ /**
+ * Gets the index of the next element.
+ *
+ * @return the index of the next element in the iterator
+ */
+ public int nextIndex() {
+ return iterator.previousIndex();
+ }
+
+ /**
+ * Checks whether there is a previous element.
+ *
+ * @return true if there is a previous element
+ */
+ public boolean hasPrevious() {
+ return iterator.hasNext();
+ }
+
+ /**
+ * Gets the previous element.
+ * The next element is the previous in the list.
+ *
+ * @return the previous element in the iterator
+ */
+ public Object previous() {
+ Object obj = iterator.next();
+ validForUpdate = true;
+ return obj;
+ }
+
+ /**
+ * Gets the index of the previous element.
+ *
+ * @return the index of the previous element in the iterator
+ */
+ public int previousIndex() {
+ return iterator.nextIndex();
+ }
+
+ /**
+ * Removes the last returned element.
+ *
+ * @throws UnsupportedOperationException if the list is unmodifiable
+ * @throws IllegalStateException if there is no element to remove
+ */
+ public void remove() {
+ if (validForUpdate == false) {
+ throw new IllegalStateException("Cannot remove from list until next() or previous() called");
+ }
+ iterator.remove();
+ }
+
+ /**
+ * Replaces the last returned element.
+ *
+ * @param obj the object to set
+ * @throws UnsupportedOperationException if the list is unmodifiable
+ * @throws IllegalStateException if the iterator is not in a valid state for set
+ */
+ public void set(Object obj) {
+ if (validForUpdate == false) {
+ throw new IllegalStateException("Cannot set to list until next() or previous() called");
+ }
+ iterator.set(obj);
+ }
+
+ /**
+ * Adds a new element to the list between the next and previous elements.
+ *
+ * @param obj the object to add
+ * @throws UnsupportedOperationException if the list is unmodifiable
+ * @throws IllegalStateException if the iterator is not in a valid state for set
+ */
+ public void add(Object obj) {
+ // the validForUpdate flag is needed as the necessary previous()
+ // method call re-enables remove and add
+ if (validForUpdate == false) {
+ throw new IllegalStateException("Cannot add to list until next() or previous() called");
+ }
+ validForUpdate = false;
+ iterator.add(obj);
+ iterator.previous();
+ }
+
+ /**
+ * Resets the iterator back to the start (which is the
+ * end of the list as this is a reversed iterator)
+ */
+ public void reset() {
+ iterator = list.listIterator(list.size());
+ }
+
+}
Propchange: jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ReverseListIterator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/iterators/ReverseListIterator.java
------------------------------------------------------------------------------
svn:keywords = "author date id revision"
Modified: jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestAll.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestAll.java?rev=400329&r1=400328&r2=400329&view=diff
==============================================================================
--- jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestAll.java (original)
+++ jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestAll.java Sat May 6 09:10:31 2006
@@ -48,6 +48,7 @@
suite.addTest(TestListIteratorWrapper.suite());
suite.addTest(TestLoopingIterator.suite());
suite.addTest(TestLoopingListIterator.suite());
+ suite.addTest(TestReverseListIterator.suite());
suite.addTest(TestSingletonIterator.suite());
suite.addTest(TestSingletonIterator2.suite());
suite.addTest(TestSingletonListIterator.suite());
Added: jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestReverseListIterator.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestReverseListIterator.java?rev=400329&view=auto
==============================================================================
--- jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestReverseListIterator.java (added)
+++ jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestReverseListIterator.java Sat May 6 09:10:31 2006
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections.iterators;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.apache.commons.collections.ResettableListIterator;
+
+/**
+ * Tests the ReverseListIterator.
+ *
+ * @version $Revision: $ $Date$
+ */
+public class TestReverseListIterator extends AbstractTestListIterator {
+
+ protected String[] testArray = { "One", "Two", "Three", "Four" };
+
+ public static void main(String args[]) {
+ String[] testCaseName = { TestReverseListIterator.class.getName() };
+ TestRunner.main(testCaseName);
+ }
+
+ public static Test suite() {
+ return new TestSuite(TestReverseListIterator.class);
+ }
+
+ public TestReverseListIterator(String testName) {
+ super(testName);
+ }
+
+ public ListIterator makeEmptyListIterator() {
+ List list = new ArrayList();
+ return new ReverseListIterator(list);
+ }
+
+ public ListIterator makeFullListIterator() {
+ List list = new ArrayList(Arrays.asList(testArray));
+ return new ReverseListIterator(list);
+ }
+
+ // overrides
+ //-----------------------------------------------------------------------
+ public void testEmptyListIteratorIsIndeedEmpty() {
+ ListIterator it = makeEmptyListIterator();
+
+ assertEquals(false, it.hasNext());
+ assertEquals(-1, it.nextIndex()); // reversed index
+ assertEquals(false, it.hasPrevious());
+ assertEquals(0, it.previousIndex()); // reversed index
+
+ // next() should throw a NoSuchElementException
+ try {
+ it.next();
+ fail("NoSuchElementException must be thrown from empty ListIterator");
+ } catch (NoSuchElementException e) {
+ }
+
+ // previous() should throw a NoSuchElementException
+ try {
+ it.previous();
+ fail("NoSuchElementException must be thrown from empty ListIterator");
+ } catch (NoSuchElementException e) {
+ }
+ }
+
+ public void testWalkForwardAndBack() {
+ ArrayList list = new ArrayList();
+ ListIterator it = makeFullListIterator();
+ while (it.hasNext()) {
+ list.add(it.next());
+ }
+
+ // check state at end
+ assertEquals(false, it.hasNext());
+ assertEquals(true, it.hasPrevious());
+
+ // this had to be commented out, as there is a bug in the JDK before JDK1.5
+ // where calling previous at the start of an iterator would push the cursor
+ // back to an invalid negative value
+// try {
+// it.next();
+// fail("NoSuchElementException must be thrown from next at end of ListIterator");
+// } catch (NoSuchElementException e) {
+// }
+
+ // loop back through comparing
+ for (int i = list.size() - 1; i >= 0; i--) {
+ assertEquals("" + i, list.size() - i - 2, it.nextIndex()); // reversed index
+ assertEquals(list.size() - i - 1, it.previousIndex()); // reversed index
+
+ Object obj = list.get(i);
+ assertEquals(obj, it.previous());
+ }
+
+ // check state at start
+ assertEquals(true, it.hasNext());
+ assertEquals(false, it.hasPrevious());
+ try {
+ it.previous();
+ fail("NoSuchElementException must be thrown from previous at start of ListIterator");
+ } catch (NoSuchElementException e) {
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ public void testReverse() {
+ ListIterator it = makeFullListIterator();
+ assertEquals(true, it.hasNext());
+ assertEquals(3, it.nextIndex());
+ assertEquals(false, it.hasPrevious());
+ assertEquals(4, it.previousIndex());
+ assertEquals("Four", it.next());
+ assertEquals(2, it.nextIndex());
+ assertEquals(true, it.hasNext());
+ assertEquals(3, it.previousIndex());
+ assertEquals(true, it.hasPrevious());
+ assertEquals("Three", it.next());
+ assertEquals(true, it.hasNext());
+ assertEquals(1, it.nextIndex());
+ assertEquals(true, it.hasPrevious());
+ assertEquals(2, it.previousIndex());
+ assertEquals("Two", it.next());
+ assertEquals(true, it.hasNext());
+ assertEquals(0, it.nextIndex());
+ assertEquals(true, it.hasPrevious());
+ assertEquals(1, it.previousIndex());
+ assertEquals("One", it.next());
+ assertEquals(false, it.hasNext());
+ assertEquals(-1, it.nextIndex());
+ assertEquals(true, it.hasPrevious());
+ assertEquals(0, it.previousIndex());
+ assertEquals("One", it.previous());
+ assertEquals("Two", it.previous());
+ assertEquals("Three", it.previous());
+ assertEquals("Four", it.previous());
+ }
+
+ public void testReset() {
+ ResettableListIterator it = (ResettableListIterator) makeFullListIterator();
+ assertEquals("Four", it.next());
+ it.reset();
+ assertEquals("Four", it.next());
+ it.next();
+ it.next();
+ it.reset();
+ assertEquals("Four", it.next());
+ }
+
+}
Propchange: jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestReverseListIterator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/iterators/TestReverseListIterator.java
------------------------------------------------------------------------------
svn:keywords = "author date id revision"
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org