List.remove() has two overloads: remove(Object) removes a matching value, while remove(int) removes the element at an index. With List<Integer>, remove(0) therefore removes index 0 rather than the value 0. section 8.9 section 8.14
The boxed-integer overload trap
List<Integer> offsets = getOffsets(); offsets.remove(0); removes the first element unconditionally. To remove the value 0, use offsets.remove((Integer) 0); or check the boolean result from remove(Object). section 8.9
Removing list elements by ascending index can skip entries because every removal shifts later elements backward. This failure may survive testing when the removal condition is rarely true; decrement the index, avoid incrementing after removal, iterate backward, or use removeIf(), subList().clear(), Iterator.remove(), or ListIterator.remove(). section 8.10 section 8.14
for (int i = data.size() - 1; i >= 0; i--) {
if (condition(data.get(i), i)) {
data.remove(i);
}
}
Compare backward index traversal with ascending removal to see how reverse iteration avoids shifting past unexamined elements. section 8.10
For queues, remove() retrieves and removes an element but throws when the queue is empty. Checking isEmpty() first is not atomic under concurrent consumption; poll() performs one operation and returns null when empty. section 9.12
