Como corrigir ConcurrentModificationException ao iterar sobre uma lista?
O erro ConcurrentModificationException
ocorre quando uma coleção é modificada enquanto está sendo percorrida por um iterador. Esse erro é comum em loops for-each
ou ao utilizar iteradores padrão para remover elementos.
Causas comuns do erro ConcurrentModificationException
Remover ou adicionar elementos em uma lista enquanto itera sobre ela com um loop for-each
.
Utilizar iteradores padrão ao modificar a coleção.
Iterar sobre coleções que não suportam modificações concorrentes.
Exemplo de erro e solução
Código que gera o erro:
import java.util.ArrayList;
import java.util.List;
public class Exemplo {
public static void main(String[] args) {
List<String> lista = new ArrayList<>();
lista.add("A");
lista.add("B");
lista.add("C");
for (String item : lista) {
if (item.equals("B")) {
lista.remove(item); // Lançará ConcurrentModificationException
}
}
}
}
Correção:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Exemplo {
public static void main(String[] args) {
List<String> lista = new ArrayList<>();
lista.add("A");
lista.add("B");
lista.add("C");
Iterator<String> iterador = lista.iterator();
while (iterador.hasNext()) {
if (iterador.next().equals("B")) {
iterador.remove(); // Remoção segura usando Iterator
}
}
}
}
O erro ocorre porque a lista é modificada enquanto está sendo iterada no for-each
. A solução correta é utilizar um Iterator
, que permite a remoção segura de elementos.
Como evitar ConcurrentModificationException?
Utilize Iterator.remove()
para modificar a coleção durante a iteração.
Caso precise modificar a lista, crie uma cópia temporária para evitar concorrência.
Utilize coleções concorrentes como CopyOnWriteArrayList
se necessário.
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.List;
public class Exemplo {
public static void main(String[] args) {
List<String> lista = new CopyOnWriteArrayList<>();
lista.add("A");
lista.add("B");
lista.add("C");
for (String item : lista) {
if (item.equals("B")) {
lista.remove(item); // Seguro em CopyOnWriteArrayList
}
}
}
}
Conclusão
O erro ConcurrentModificationException
pode ser evitado ao usar Iterator.remove()
para modificações seguras, evitar loops for-each
ao remover elementos e utilizar coleções concorrentes quando necessário. Essas práticas ajudam a garantir maior estabilidade ao manipular listas em Java.
Por que ConcurrentModificationException ocorre e como preveni-lo?
O erro ConcurrentModificationException ocorre com frequência em aplicações que lidam com listas dinâmicas. Quando modificamos uma coleção enquanto ela está sendo percorrida, o iterador perde a referência, resultando nesse erro. Entender como os iteradores funcionam e quando usar coleções concorrentes é essencial para evitar esse problema.
Algumas aplicações:
- Manipulação segura de listas durante iteração
- Evitar falhas inesperadas ao remover elementos
- Garantir integridade de dados ao trabalhar com múltiplas threads
- Uso de coleções concorrentes para aplicações multi-thread
Dicas para quem está começando
- Evite modificar coleções diretamente dentro de loops for-each
- Use Iterator para remover elementos de uma lista durante a iteração
- Utilize CopyOnWriteArrayList para listas que podem ser modificadas durante a iteração
- Faça cópias temporárias da lista antes de modificá-la
Contribuições de Rodrigo Farias