TheAlgorithms/Java · error · IllegalStateException

Cannot remove element before calling next()

Error message

Cannot remove element before calling next()

What it means

The DynamicArray iterator's remove() follows the standard Java Iterator contract: it can only be called once per next() call. The cursor starts at 0; calling remove() before any next() (cursor <= 0) or calling it twice after a single next() (cursor was decremented back to 0) throws IllegalStateException.

Source

Thrown at src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java:258

        public E next() {
            checkForComodification();
            if (cursor >= size) {
                throw new NoSuchElementException();
            }
            return (E) elements[cursor++];
        }

        /**
         * Removes the last element returned by this iterator.
         *
         * @throws IllegalStateException if the next method has not yet been called, or
         *                               the remove method has already been called after
         *                               the last call to the next method
         */
        @Override
        public void remove() {
            if (cursor <= 0) {
                throw new IllegalStateException("Cannot remove element before calling next()");
            }
            checkForComodification();
            DynamicArray.this.remove(--cursor);
            expectedModCount = modCount;
        }

        /**
         * Checks for concurrent modifications to the array during iteration.
         *
         * @throws ConcurrentModificationException if the array has been modified
         *                                         structurally
         */
        private void checkForComodification() {
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
        }

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Always call next() immediately before remove() in the loop body
  2. Use the stream API or a collection removeIf pattern instead of manual iterator removal
  3. Track whether next() was called with a boolean flag if the removal is conditional

Example fix

// before — remove() called before next()
Iterator<String> it = arr.iterator();
while (it.hasNext()) {
    it.remove(); // throws IllegalStateException
    it.next();
}

// after — next() before remove()
Iterator<String> it = arr.iterator();
while (it.hasNext()) {
    String e = it.next();
    if (shouldRemove(e)) it.remove();
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure next() is called before remove().
Iterator<String> it = arr.iterator();
boolean canRemove = false;
while (it.hasNext()) {
    String e = it.next();
    canRemove = true;
    if (shouldRemove(e)) {
        it.remove();
        canRemove = false; // must call next() again before next remove()
    }
}

Try / catch

try {
    it.remove();
} catch (IllegalStateException e) {
    // next() was not called or remove() was called twice — skip
    logger.debug("Iterator.remove() called in illegal state");
}

Prevention

When it happens

Trigger: Calling iterator.remove() before any iterator.next(). Calling remove() twice without an intervening next(). Calling remove() on a fresh iterator without advancing.

Common situations: Forgetting to call next() inside a while(hasNext()) loop before remove(). Calling remove() in a filter predicate without advancing the iterator. Copy-paste of a removal pattern that omits the next() call.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/dc212cb03c2f42b1. Report an issue: GitHub.