Main Tutorials

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

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.

1. java.util.ConcurrentModificationException

If we remove an item from an ArrayList while iterating it, the list.remove(s) will throws java.util.ConcurrentModificationException.

IteratorApp1.java

package com.mkyong.basic;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class IteratorApp1 {

  public static void main(String[] args) {

      List<String> list = new ArrayList<>();
      list.add("A");
      list.add("B");
      list.add("C");

      for (String s : list) {
          if ("A".equals(s)) {
              // throws java.util.ConcurrentModificationException
              list.remove(s);
          }
      }

      System.out.println(list);

  }

}

Output

Terminal

Exception in thread "main" java.util.ConcurrentModificationException

at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1042)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:996)
at com.mkyong.basic.IteratorApp.main(IteratorApp.java:16)

2. Java 8 Collection#removeIf

In Java 8, we can use the Collection#removeIf API to remove items from a List while iterating it.

2.1 removeIf examples

IteratorApp2A.java

package com.mkyong.basic;

import java.util.ArrayList;
import java.util.List;

public class IteratorApp2A {

  public static void main(String[] args) {

      List<String> list = new ArrayList<>();
      list.add("A");
      list.add("B");
      list.add("C");

      // remove if item is "A"
      list.removeIf("A"::equals);

      System.out.println(list);

  }

}

Output

Terminal

[B, C]

Another removeIf example.

IteratorApp2B.java

package com.mkyong.basic;

import java.util.ArrayList;
import java.util.List;

public class IteratorApp2B {

  public static void main(String[] args) {

      List<Integer> list = new ArrayList<>();
      list.add(1);
      list.add(2);
      list.add(3);

      // remove if item is 1 or 3
      list.removeIf(x -> x == 1 || x == 3);

      System.out.println(list);

  }

}

Output

Terminal

[2]

2.2 removeIf uses Iterator

Review the Java 8 Collection#removeIf method signature, and the API uses Iterator to remove the item while iterating it.

Collection.java

package java.util;

public interface Collection<E> extends Iterable<E> {

  //...

  default boolean removeIf(Predicate<? super E> filter) {
      Objects.requireNonNull(filter);
      boolean removed = false;
      final Iterator<E> each = iterator();
      while (each.hasNext()) {
          if (filter.test(each.next())) {
              each.remove();
              removed = true;
          }
      }
      return removed;
  }

  //...
}

3. ListIterator example

Before Java 8, we can use ListIterator to remove the items from a List while iterating it.

IteratorApp3.java

package com.mkyong.basic;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class IteratorApp3 {

    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");

        ListIterator<String> iter = list.listIterator();
        while(iter.hasNext()){
            if("A".equals(iter.next())){
                iter.remove();
            }
        }

        System.out.println(list);

    }

}

Output

Terminal

[B, C]

4. Filter and Collect example

4.1 We also can create a new List to store the filtered result.

IteratorApp4A.java

package com.mkyong.basic;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class IteratorApp4A {

  public static void main(String[] args) {

      List<String> list = new ArrayList<>();
      list.add("A");
      list.add("B");
      list.add("C");

      List<String> result = new ArrayList<>();
      for (String s : list) {
          if (!"A".equals(s)) {
              result.add(s);
          }
      }

      System.out.println(result);

  }

}

Output

Terminal

[B, C]

4.2 In Java 8, we can use a stream to filter and collect.

IteratorApp4B.java

package com.mkyong.basic;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class IteratorApp4B {

  public static void main(String[] args) {

      List<String> list = new ArrayList<>();
      list.add("A");
      list.add("B");
      list.add("C");

      // Java 8
      List<String> result = list
              .stream()
              .filter(x -> !"A".equals(x))
              .collect(Collectors.toList());

      System.out.println(result);

  }

}

Output

Terminal

[B, C]

5. References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Nader
1 year ago

I deeply love your website and your articles. they are awesome.
Thank you for sharing.

I believe the second approach that you said, is incorrect. because if your watch the ArrayList source code, it overrides the removeIf() method and it again has checked the modCount to detect the concurrent modification.

Zbyszek
2 years ago

Thanks. I prefer solution from pt. 3