Avoiding ConcurrentModificationException when removing collection objects in a loop?

+1 vote
333 views
asked Nov 22, 2020 by Rahul Singh (682 points)  

In Java, I am iterating over a loop and want to update the collection at the same time by removing elements matching certain criteria.

List<String> names = ....
for (String name : names) {
   // Do something
   if (names.equals("testName")){
     names.remove(name)
   }
}

Is it possible to do that as currently it throws error with the code above?

1 Answer

+1 vote
answered Nov 23, 2020 by Hitesh Garg (799 points)  
selected Nov 23, 2020 by Rahul Singh
 
Best answer

Iterator.remove()

To update a collection while iterating we can use Iterator.remove()

List<String> list = new ArrayList<>();

Iterator<Integer> iter = list.iterator();
while (iter.hasNext()) {
    if (iter.next() == 5) {
        iter.remove();  // <<--- 
    }
}

Java 8 Collection.removeIf

This also uses iterator but the syntax is quite eassier

var list = new ArrayList<>(List.of("a", "b", "c", "a1"));

list.removeIf(x -> x.startsWith("a"));  // <<--- 

System.out.println(list); // Output -> [b, c]

Java 8 Streams

I would still prefer using immutable collections and use the stream functions instead of updating the collection in place..

var list = List.of("a", "b", "c", "a1");    
var updatedList = list.stream()
    .dropWhile(x -> x.startsWith("a"))
    .collect(Collectors.toList());
System.out.println(updatedList); // Output -> [b, c]
...