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
- Always call next() immediately before remove() in the loop body
- Use the stream API or a collection removeIf pattern instead of manual iterator removal
- 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
- Always call next() before remove() in the loop body
- For filtering, prefer stream().filter() or removeIf() over manual iterator removal
- After calling remove(), do not call it again until after the next next()
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
- Huffman tree is empty.
- No more elements in the bag.
- Capacity cannot be negative.
- Index cannot be negative.
- Index: {index}, Size: {size}
AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13).
Data as JSON: /api/errors/dc212cb03c2f42b1.
Report an issue: GitHub.