This post will discuss how to remove elements from a mutable list in Java that satisfies the given predicate.

Fail Fast Iterator vs Fail Safe Iterator in Java

 
It is not allowed to modify a list (add elements to it, remove elements from it, etc.) while iterating over it; otherwise, a ConcurrentModificationException will be thrown to avoid non-deterministic behavior. We can use any of the following methods to efficiently remove elements from the list that matches the given predicate without throwing ConcurrentModificationException.

1. Using an iterator

The Iterator interface provides the remove() method, which removes the last element returned by the iterator. The idea is to get an iterator to the given list and use the remove() method to remove elements on which the predicate is satisfied.

 
Please note that the iterator will throw a ConcurrentModificationException if the list is modified after it is created except through the iterator’s own remove method.

2. Using removeAll() method

We can maintain a separate collection containing elements from the original list that matches the given predicate. Then we can use the removeAll() method provided by the List interface to remove elements of that collection from the original list.

3. Using Java 8

In Java 8, we can use Stream to remove elements from a list by filtering the stream easily.

⮚ Using Collectors

The idea is to convert the specified list to a sequential Stream, filter the stream and accumulate the elements that match the given predicate into a new list using a Collector.

 
Please note that this method will return a new list instance, and the original list remains unchanged. Also, it doesn’t guarantee the type of the List returned, so we can use Collectors.toCollection() to specify the desired list type:

⮚ Using forEach() with List.add()

This is similar to the earlier approach, where we maintain a separate collection containing the elements from the original list that matches the given predicate and using the List.removeAll() method to remove those elements from the original list.

 
We can also perform filtering inside the forEach() method, as shown below:

⮚ Using forEach() with List.remove()

Since we can’t modify a list while iterating over it, we can create a duplicate list and remove elements that satisfy the predicate from the original list by iterating over the duplicate list.

The following code uses Java 8 Stream to do the filtering, but we can also use an iterator or a for-each loop.

 
We can also perform filtering inside the forEach() method, as shown below:

⮚ Using removeIf()

The List interface provides the removeIf() method that removes all the list elements that satisfy the given predicate. This is the simplest approach among all approaches discussed above and uses Iterator.remove() behind the scenes.

That’s all about removing elements from a list that satisfies a given predicate in Java.

 
Suggested Read:

Remove elements from a list while iterating over it in Java