diff --git a/src/changes/changes.xml b/src/changes/changes.xml index a98d8066f..2adc1862b 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -22,6 +22,10 @@ + + Tree traversal with a TreeListIterator will not be affected anymore by + the removal of an element directly after a call to previous(). + Added "IndexedCollection" collection decorator which provides a map-like view on an existing collection. diff --git a/src/main/java/org/apache/commons/collections/list/TreeList.java b/src/main/java/org/apache/commons/collections/list/TreeList.java index 25ec94dd9..390ed338d 100644 --- a/src/main/java/org/apache/commons/collections/list/TreeList.java +++ b/src/main/java/org/apache/commons/collections/list/TreeList.java @@ -900,15 +900,14 @@ public class TreeList extends AbstractList { if (currentIndex == -1) { throw new IllegalStateException(); } - if (nextIndex == currentIndex) { - // remove() following previous() - next = next.next(); - parent.remove(currentIndex); - } else { + parent.remove(currentIndex); + if (nextIndex != currentIndex) { // remove() following next() - parent.remove(currentIndex); nextIndex--; } + // the AVL node referenced by next may have become stale after a remove + // reset it now: will be retrieved by next call to next()/previous() via nextIndex + next = null; current = null; currentIndex = -1; expectedModCount++; diff --git a/src/test/java/org/apache/commons/collections/list/TreeListTest.java b/src/test/java/org/apache/commons/collections/list/TreeListTest.java index 1d780edcc..a5d57050c 100644 --- a/src/test/java/org/apache/commons/collections/list/TreeListTest.java +++ b/src/test/java/org/apache/commons/collections/list/TreeListTest.java @@ -46,6 +46,7 @@ public class TreeListTest extends AbstractListTest { // benchmark(new java.util.ArrayList()); // System.out.print("\n LinkedList = "); // benchmark(new java.util.LinkedList()); +// System.out.print("\n NodeCachingLinkedList = "); // benchmark(new NodeCachingLinkedList()); // } @@ -246,5 +247,25 @@ public class TreeListTest extends AbstractListTest { assertEquals(new Integer(4), li.next()); assertEquals(false, li.hasNext()); } + + public void testBugCollections447() { + final List treeList = new TreeList(); + treeList.add("A"); + treeList.add("B"); + treeList.add("C"); + treeList.add("D"); + + final ListIterator li = treeList.listIterator(); + assertEquals("A", li.next()); + assertEquals("B", li.next()); + + assertEquals("B", li.previous()); + + li.remove(); // Deletes "B" + + // previous() after remove() should move to + // the element before the one just removed + assertEquals("A", li.previous()); + } }