Java remove Object from list ConcurrentModificationException

1. Introduction

In this article, we'll take a look at the ConcurrentModificationException class.

First, we'll give an explanation how it works, and then prove it by using a test for triggering it.

Finally, we'll try out some workarounds by using practical examples.

1. ArrayList remove() method Example

Now, let's see an example of removing elements from ArrayList while looping using for()loop and ArrayList.remove() method, which is wrong, and the program will throw ConcurrentModificationExcetpion upon execution.

import java.util.ArrayList; import java.util.List; /* * Java Program to remove an element while iterating over ArrayList */ public class Main { public static void main(String[] args) throws Exception { List<String> loans = new ArrayList<>(); loans.add("personal loan"); loans.add("home loan"); loans.add("auto loan"); loans.add("credit line loan"); loans.add("mortgage loan"); loans.add("gold loan"); // printing ArrayList before removing any element System.out.println(loans); // removing element using ArrayList's remove method during iteration // This will throw ConcurrentModification for (String loan : loans) { if (loan.equals("personal loan")) { loans.remove(loan); } } // printing ArrayList after removing an element System.out.println(loans); } }
Output
Exception in thread "main" [personal loan, home loan, auto loan, credit line loan, mortgage loan, gold loan]
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at Main.main(Main.java:26)


Some of you may wonder that we are getting ConcurrentModificationException because we are not using the Iterator, but that's not true, even if you use Iterator you will get java.util.ConcurrentModificationException as long as you will use ArrayList's remove() method for removing element while iterating as shown in the following example:

Iterator<String> itr = loans.iterator(); while (itr.hasNext()) { String loan = itr.next(); if (loan.equals("personal loan")) { loans.remove(loan); } }

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at Main.main(Main.java:29)


In order to fix the above code, you just need to remove the loans.remove(loan) with the itr.remove()method, which is explained in the next example. Though, if you want to know more about Iterator and in general Java Collection Framework, which can feel daunting sometimes, I suggest you go throughJava Fundamentals: Collectionscourse on Pluralsight.


It's a perfect course to both learn and master the Java Collection framework and I highly recommend you to join this course.




Solving ConcurrentModificationException in ArrayList

Here is the Java program to demonstrate one scenario where you get the ConcurrentModificationException even if just one thread is modifying the ArrayList. In this example, we are looping over ArrayList using advanced for loop and removing selected elements, but because we are using ArrayList's remove() method.


import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; /** * Java Program to demonstrate how to deal with * ConcurrentModificationException. * Unlike the name suggests, this error can come even if only * one thread is modifying the collection e.g. List. * It happens when you modify collection * while iterating over it e.g. adding new element or removing elements. * * If you want to remove elements while traversing list then * make sure you use Iterator's remove() method or not ArrayList's remove() * method() to avoid ConcurrentModificationExcetpion. * * @author WINDOWS 8 * */ public class ConcurrentModExceptionDemo{ public static void main(String args[]) { List<String> listOfPhones = new ArrayList<String>(Arrays.asList( "iPhone 6S", "iPhone 6", "iPhone 5", "Samsung Galaxy 4", "Lumia Nokia")); System.out.println("list of phones: " + listOfPhones); // Iterating and removing objects from list // This is wrong way, will throw ConcurrentModificationException for(String phone : listOfPhones){ if(phone.startsWith("iPhone")){ // listOfPhones.remove(phone); // will throw exception } } // The Right way, iterating elements using Iterator's remove() method for(Iterator<String> itr = listOfPhones.iterator(); itr.hasNext();){ String phone = itr.next(); if(phone.startsWith("iPhone")){ // listOfPhones.remove(phone); // wrong again itr.remove(); // right call } } System.out.println("list after removal: " + listOfPhones); } } Output : list of phones: [iPhone 6S, iPhone 6, iPhone 5, Samsung Galaxy 4, Lumia Nokia] list after removal: [Samsung Galaxy 4, Lumia Nokia]
If you uncomment the commented code in the first loop and second loop, you will get the following exception:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at dto.ReverseArrayInPlace.main(ReverseArrayInPlace.java:28)

because we are using ArrayList's remove() method. In the second example, we have used theremove() method of Iterator and that's why we are successfully able to delete selected elements from the ArrayList without ConcurrentModificationException.

Here is a summary of important points about solving ConcurrentModificationException while looping over ArrayList in Java :



That's all about how to deal with ConcurrentModificationException in Java. The biggest thing to learn and remember is that this error can come even if you have just one thread modifying collection e.g. removing elements while looping over the list.


Related troubleshooting guides
Here are some handy Java tips to solve some common errors and exceptions in Java:
  • How to deal withjava.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlObject? (solution)
  • How to solve "could not create the Java virtual machine" error in Java? (solution)
  • Fixing java.lang.unsupportedclassversionerror unsupported major.minor version 50.0 (solution)
  • java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory error (solution)
  • How to solvejava.lang.ClassNotFoundException: com.mysql.jdbc.Driver error? (hint)
  • How to solvejava.lang.classnotfoundexception oracle.jdbc.driver.oracledriver? (solution)
  • java.lang.ClassNotFoundException : org.Springframework.
    Web.Context.ContextLoaderListener (solution)
  • How to fix 'javac' is not recognized as an internal or external command(solution)
  • How to fix Caused By: java.lang.NoClassDefFoundError: org/apache/log4j/Logger (solution)
  • How to solve java.lang.OutOfMemoryError: Java Heap Space in Eclipse, Tomcat? (solution)

ConcurrentModificationException in Single Thread

This is the first example of reproducing the concurrent modification exception in Java. In this program, we are iterating over ArrayList using the enhanced foreach loop and removing selective elements e.g. an element that matches certain conditions using ArrayList's remove method.

For example, in the below code we have first added a couple of good programming books likeProgramming Pearls, Clean Code, Effective Java, and Code Complete into ArrayList and then removing any element which has Code in its title.

package beginner; import java.util.ArrayList; import java.util.List; public class HelloWorldApp{ public static void main(String... args){ List<String> listOfBooks = new ArrayList<>(); listOfBooks.add("Programming Pearls"); listOfBooks.add("Clean Code"); listOfBooks.add("Effective Java"); listOfBooks.add("Code Complete"); // Using forEach loop to iterate and removing // element during iteration will throw // ConcurrentModificationException in Java for(String book: listOfBooks){ if(book.contains("Code"));{ listOfBooks.remove(book); } } } } 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 beginner.HelloWorldApp.main(HelloWorldApp.java:18)

You can see that this error comes even though we just have one thread, the main thread which is operating with ArrayList. The ConcurrentModification error comes because we are not using Iterator, instead just calling listOfBooks.remove() method.

In this code, I have used Java 1.5 enhanced for loop, you must know how enhanced for loop works in Java.

Difference between for loop and enhanced for loop is that later internally uses an Iterator for going over all elements of a collection. For a more in-depth discussion, see here



Java – How to remove items from a List while iterating?

By | Last updated: May 12, 2021

Viewed: 14,231 (+351 pv/w)

Tags:iterator | java 8 | java collections | list | loop list | predicate

In Java, if we remove items from a List while iterating it, it will throw java.util.ConcurrentModificationException. This article shows a few ways to solve it.

Table of contents

P.S Tested with Java 11.

Video liên quan

Postingan terbaru

LIHAT SEMUA