diff --git a/src/main/java/org/apache/commons/collections4/iterators/ListIteratorWrapper.java b/src/main/java/org/apache/commons/collections4/iterators/ListIteratorWrapper.java index aeed9d0a2e..cfa44d0165 100644 --- a/src/main/java/org/apache/commons/collections4/iterators/ListIteratorWrapper.java +++ b/src/main/java/org/apache/commons/collections4/iterators/ListIteratorWrapper.java @@ -74,6 +74,9 @@ public class ListIteratorWrapper implements ResettableListIterator { /** Recall whether the wrapped iterator's "cursor" is in such a state as to allow remove() to be called */ private boolean removeState; + /** Recall whether the element last returned by the wrapped iterator can still be removed from it */ + private boolean wrappedRemovable; + /** * Constructs a new {@code ListIteratorWrapper} that will wrap * the given iterator. @@ -145,6 +148,7 @@ public E next() throws NoSuchElementException { if (currentIndex < wrappedIteratorIndex) { ++currentIndex; + removeState = wrappedRemovable && currentIndex == wrappedIteratorIndex; return list.get(currentIndex - 1); } @@ -152,6 +156,7 @@ public E next() throws NoSuchElementException { list.add(retval); ++currentIndex; ++wrappedIteratorIndex; + wrappedRemovable = true; removeState = true; return retval; } @@ -187,7 +192,7 @@ public E previous() throws NoSuchElementException { if (currentIndex == 0) { throw new NoSuchElementException(); } - removeState = wrappedIteratorIndex == currentIndex; + removeState = wrappedRemovable && wrappedIteratorIndex == currentIndex; return list.get(--currentIndex); } @@ -228,6 +233,7 @@ public void remove() throws IllegalStateException { list.remove(removeIndex); currentIndex = removeIndex; wrappedIteratorIndex--; + wrappedRemovable = false; removeState = false; } @@ -247,6 +253,7 @@ public void reset() { return; } currentIndex = 0; + removeState = false; } /** diff --git a/src/test/java/org/apache/commons/collections4/iterators/ListIteratorWrapperTest.java b/src/test/java/org/apache/commons/collections4/iterators/ListIteratorWrapperTest.java index b24ecf47ce..30d15362d4 100644 --- a/src/test/java/org/apache/commons/collections4/iterators/ListIteratorWrapperTest.java +++ b/src/test/java/org/apache/commons/collections4/iterators/ListIteratorWrapperTest.java @@ -180,6 +180,33 @@ public void testRemove() { } + @Test + void testRemoveAfterReset() { + final ResettableListIterator iter = makeObject(); + iter.next(); + iter.reset(); + + assertThrows(IllegalStateException.class, iter::remove, + "ListIteratorWrapper#remove() should fail; must be repositioned after reset()"); + assertEquals(testArray.length, list1.size()); + } + + @Test + void testRemoveAfterReturningToWrappedPosition() { + final ListIterator iter = makeObject(); + iter.next(); + iter.next(); + iter.previous(); + iter.previous(); + // read forwards out of the cache until back at the wrapped iterator's position + iter.next(); + final E second = iter.next(); + + iter.remove(); + assertEquals(testArray.length - 1, list1.size()); + assertFalse(list1.contains(second), "remove() should drop the element last returned by next()"); + } + @Test void testReset() { final ResettableListIterator iter = makeObject();