Efficiently removing elements while iterating a collection in Java

One of the common problem while removing elements from an ArrayList in Java is the ConcurrentModificationException. If you use classical for loop with the index or enhanced for loop and try to remove an element from the ArrayList using remove() method, you will get the ConcurrentModificationException but if you use Iterator’s remove method or ListIterator’s remove() method, then you won’t get this error and be able to remove the element. It’s an unwritten rule in Java that while looping through the list, you should not add() or remove() elements until the collection supports fail-safe Iterator e.g. CopyOnWriteArrayList, which operate on a copy of list rather than the original list.

Example – Wrong way to delete

import java.util.ArrayList;
import java.util.Iterator;

public class SafelyRemoveFromCollections {

	public static void main(String[] args) {

		ArrayList<Integer> lst = new ArrayList<Integer>();
		lst.add(11);
		lst.add(12);
		lst.add(13);
		lst.add(14);

		for (Integer iin : lst) {
			if (iin == 12) {
				lst.remove(iin); // will throw exception
			}
		}
	}
}

Output

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
	at java.util.ArrayList$Itr.next(Unknown Source)
	at collections.SafelyRemoveFromCollections.main(SafelyRemoveFromCollections.java:17)

Correct way to delete (using iterators)


package collections;

import java.util.ArrayList;
import java.util.Iterator;

public class SafelyRemoveFromCollections {

	public static void main(String[] args) {

		ArrayList<Integer> lst = new ArrayList<Integer>();
		lst.add(11);
		lst.add(12);
		lst.add(13);
		lst.add(14);

		Iterator<Integer> iter = lst.iterator();

		System.out.println("-------Before deleting---------");
		display(lst);

		while (iter.hasNext()) {
			if (iter.next() == 12) {
				iter.remove();
			}
		}

		System.out.println("-------After deleting---------");
		display(lst);
	}

	private static void display(ArrayList<Integer> lst) {
		for (Integer a : lst)
			System.out.println(a);

	}

}

Output

-------Before deleting---------
11
12
13
14
-------After deleting---------
11
13
14

Leave a Reply

Your email address will not be published. Required fields are marked *