Friday, August 27, 2021

How to Remove Objects From ArrayList while Iterating in Java - Example Tutorial

One of the common problems many Java Programmers face is to remove elements while iterating over ArrayList in Java because the intuitive solution doesn't work like you just cannot go through an ArrayList using a for loop and remove an element depending upon some condition. Even though java.util.ArrayList provides the remove() methods, like remove (int index) and remove (Object element), you cannot use them to remove items while iterating over ArrayList in Java because they will throw ConcurrentModificationException if called during iteration. The right way to remove objects from ArrayList while iterating over it is by using the Iterator's remove() method.

When you use iterator's remove() method, ConcurrentModfiicationException is not thrown. Because it also updates the counters and variables used by the Iterator like modCount, which indicates that modification is done by the Iterator itself and not somewhere around.

In this article, I'll show you an example of both ways and how they work in Java. You'll also learn a little bit about java.util.ConcurrentModificationException, which is a common problem for non-concurrent collection classes like ArrayList or HashMap.

Though, if you are entirely new to Java and coming from a non-programming background, I suggest you to first go through a comprehensive Java course like The Complete Java MasterClass instead of learning from arbitrary articles.

The course provides structured learning, which is both efficient and works great for beginners. Once you know the fundamentals, you can learn any topic by reading a blog post or individual tutorial, they will make more sense by then also.





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 through Java Fundamentals: Collections course on Pluralsight.

How to Remove Objects or Elements while Iterating over ArrayList in Java - The Right way

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




2. Iterator's remove() method Example

Now, let's try the other approach, which uses Iterator's remove() method to remove an element from ArrayList while iterating over it.

import java.util.ArrayList;
import java.util.Iterator;
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

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

    // printing ArrayList after removing an element
    System.out.println(loans);
  }

}

Output
[personal loan, home loan, auto loan, credit line loan, mortgage loan, gold loan]
[home loan, auto loan, credit line loan, mortgage loan, gold loan]

From the output, you can see that the "personal loan" element is removed from the ArrayList. The size of the ArrayList is also reduced by one, and there is no ConcurrentModficiationException in the code.


That's all about how to remove elements while iterating over ArrayList in Java. As I have said that if you use ArrayList's remove() method like remove(int index) or remove(Object obj) while iterating over ArrayList, then a ConcurrentModfiicationException will be thrown. You can avoid that by using Iterator's remove() method, which removes the current object in the iteration.

Other ArrayList tutorials for Java Programmers
  • How to remove duplicate elements from ArrayList in Java? (tutorial)
  • 10 Courses to learn Java Programming for beginners (courses)
  • How to create and initialize ArrayList in the same line? (example)
  • 10 Free Spring Boot Courses for Java developers (courses)
  • Difference between ArrayList and HashSet in Java? (answer)
  • 10 Free Courses to learn Spring Framework (courses)
  • Difference between an Array and ArrayList in Java? (answer)
  • How to reverse an ArrayList in Java? (example)
  • Top 5 Courses to learn Hibernate for Java developers (courses)
  • How to loop through an ArrayList in Java? (tutorial)
  • How to synchronize an ArrayList in Java? (read)
  • When to use ArrayList over LinkedList in Java? (answer)
  • Difference between ArrayList and HashMap in Java? (answer)
  • Difference between ArrayList and Vector in Java? (answer)
  • How to sort an ArrayList in descending order in Java? (read)
  • How to get a sublist from ArrayList in Java? (example)
  • How to convert CSV String to ArrayList in Java? (tutorial)

Thanks for reading this article so far. If you like this article, then please share it with your friends and colleagues. If you have any questions or feedback, then please drop a note

P. S. - If you are new to the Java world and looking for a free online training course to learn Java then you can also check out this Java Tutorial for Complete Beginners course on Udemy. It's completely free and you just need a Udemy account to join this online course.

5 comments:

  1. while (itr.hasNext()) {
    String loan = itr.next();
    if (loan.equals("personal loan")) {
    itr.remove();
    }
    }

    Doesn't this while loop fail to check the first element in the sequence, since it's always checking the next?


    ReplyDelete
    Replies
    1. When @Annonymous, did you tested that? hasNext() return true if there is more element and itr.next() is required to move the pointer. I suggest you test and then we can discuss.

      Delete
  2. Why I am not getting the exception in both cases....
    Still wondering why, what I have coded wrong that I am missing the exception.

    ReplyDelete
  3. public class Main {

    public static void main(String[] args) {
    Collection students = new ArrayList();

    for (int i=0; i< 4;i++){
    Student student = new Student();
    student.name = "Lavanya"+i;
    student.age = 20 + i;

    students.add(student);
    }

    System.out.println("Before performing operations...............");
    for (Student student : students) {
    System.out.println(String.format("%s -> %d",student.name, student.age));
    }


    Iterator iterator = students.iterator();
    if (iterator.hasNext()){
    var student = iterator.next();
    if ( student.age == 21){
    iterator.remove();
    }
    }
    System.out.println();
    System.out.println("After performing remove operations...............");
    for (Student student : students) {
    System.out.println(String.format("%s -> %d",student.name, student.age));
    }
    }

    Whrere Student class has two properties name and age.
    In output i am able to see the student who has age 21.

    output:
    ------
    Before performing operations...............
    Lavanya0 -> 20
    Lavanya1 -> 21
    Lavanya2 -> 22
    Lavanya3 -> 23

    After performing remove operations...............
    Lavanya0 -> 20
    Lavanya1 -> 21
    Lavanya2 -> 22
    Lavanya3 -> 23

    Could you please explain.....

    ReplyDelete
    Replies
    1. You are using if instead of while, this means you are only checking for first student which has age 20 that's why no student is get deleted. change the code like this and it should work

      while (iterator.hasNext()){
      var student = iterator.next();
      if ( student.age == 21){
      iterator.remove();
      }

      Delete

Feel free to comment, ask questions if you have any doubt.