Why Removing Elements from a Java List Often Fails and How to Fix It
This article explains common pitfalls when deleting elements from a Java List—such as index shifting, ConcurrentModificationException in foreach loops, and the difference between removing by index versus by object—and provides reliable solutions using index adjustment, reverse iteration, and Iterator.remove().
In Java, removing elements from a List with list.remove(o) or list.remove(i) can easily produce unexpected results. The article summarizes typical traps and demonstrates correct techniques.
First, initialize a list:
package com.cicc.am.test;
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(3);
list.add(4);
System.out.println(list);
}
}Output:
[1, 2, 3, 3, 4]1. Ordinary for‑loop deletion – wrong
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == 3) list.remove(i);
}
System.out.println(list);Result: [1, 2, 3, 4]. Only one 3 is removed because after removing an element the subsequent elements shift left, causing the next duplicate to be skipped.
2. For‑loop with index adjustment – correct
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == 3) list.remove(i--);
}
System.out.println(list);Result: [1, 2, 4]. Decrementing i after removal compensates for the left shift.
3. Reverse iteration – correct
for (int i = list.size() - 1; i >= 0; i--) {
if (list.get(i) == 3) {
list.remove(i);
}
}
System.out.println(list);Result: [1, 2, 4]. Traversing from the end avoids index‑shift issues.
4. foreach loop deletion – wrong
for (Integer i : list) {
if (i == 3) list.remove(i);
}
System.out.println(list);Throws java.util.ConcurrentModificationException because the underlying list’s modCount changes while the iterator’s expectedModCount remains unchanged.
5. Deleting with an Iterator – correct
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
if (it.next() == 3) {
it.remove();
}
}
System.out.println(list);Result: [1, 2, 4]. Using Iterator.remove() updates the modification count safely.
6. Using list.remove(i) inside an iterator – wrong
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
Integer value = it.next();
if (value == 3) {
list.remove(value);
}
}
System.out.println(list);Also throws ConcurrentModificationException for the same reason as the foreach case.
7. Index vs. object removal for Integer
Calling list.remove(2) removes the element at index 2, not the value 2. To delete the object, use list.remove(new Integer(2)) or list.remove(Integer.valueOf(2)).
list.remove(new Integer(2));
System.out.println(list);Result: [1, 3, 3, 4].
Summary
When deleting elements with a for‑loop, remember that the list shifts left; adjust the index or iterate in reverse.
The safest way is to use an Iterator and its remove() method.
Be aware that list.remove(int) removes by index, while list.remove(Object) removes by value; use an Integer object to delete a specific value.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
