Evitando ConcurrentModificationException ao Remover Elementos de uma Lista em Java
Ao trabalhar com coleções em Java, especialmente listas, é comum a necessidade de remover elementos durante a iteração. No entanto, essa prática pode levar a uma exceção conhecida como ConcurrentModificationException. Este artigo explica por que isso acontece e apresenta abordagens seguras para evitar esse problema.
O que é ConcurrentModificationException?
A ConcurrentModificationException é lançada quando uma coleção é modificada estruturalmente (elementos são adicionados ou removidos) enquanto está sendo iterada por métodos como for-each ou Iterator, exceto através dos métodos do próprio Iterator. Isso ocorre porque a estrutura interna da coleção muda durante a iteração, tornando o estado da iteração inconsistente.
Exemplo do Problema
Considere o seguinte código:
List<String> nomes = new ArrayList<>();
nomes.add("Alisson");
nomes.add("Bruna");
nomes.add("Cassio");
for (String nome : nomes) {
if (nome.equals("Bruna")) {
nomes.remove(nome); // Lança ConcurrentModificationException
}
}
Ao tentar remover "Bruna" durante o laço, a exceção será lançada.
Abordagens para Evitar o Problema
1. Usando uma Lista Auxiliar
Uma abordagem segura é criar uma lista auxiliar para armazenar os elementos que devem ser removidos e, após a iteração, removê-los da lista original:
List<String> nomesParaRemover = new ArrayList<>();
for (String nome : nomes) {
if (nome.equals("Bruna")) {
nomesParaRemover.add(nome);
}
}
nomes.removeAll(nomesParaRemover);
2. Iterando Sobre uma Cópia da Lista
Outra alternativa é criar uma cópia da lista e iterar sobre ela, removendo os elementos da lista original:
List<String> copia = new ArrayList<>(nomes);
for (String nome : copia) {
if (nome.equals("Cassio")) {
nomes.remove(nome);
}
}
3. Usando o Iterator
O uso explícito do Iterator permite remover elementos de forma segura durante a iteração:
Iterator<String> iterator = nomes.iterator();
while (iterator.hasNext()) {
if (iterator.next().equals("Alisson")) {
iterator.remove();
}
}
Quando Usar Cada Abordagem?
- Lista Auxiliar: Ideal quando deseja remover todos os elementos que atendem a uma condição.
- Cópia da Lista: Útil quando a remoção é pontual ou quando a lógica exige iteração sobre o estado original.
- Iterator: Recomendado para remoção durante a iteração, especialmente quando a performance é importante e não se deseja criar listas auxiliares.
Conclusão
Remover elementos de uma lista durante a iteração exige cuidado para evitar a ConcurrentModificationException. Escolher a abordagem correta depende do contexto da aplicação e da regra de negócio. Compreender essas técnicas é fundamental para escrever código Java robusto e seguro ao manipular coleções.




Excelente, Cassio! Seu artigo sobre "Evitando ConcurrentModificationException ao Remover Elementos de uma Lista em Java" é super claro e relevante. É fascinante ver como você aborda um problema comum que muitos desenvolvedores Java enfrentam, explicando por que a ConcurrentModificationException acontece e apresentando abordagens seguras para evitá-la.
Você demonstrou que a exceção é lançada quando uma coleção é modificada durante a iteração, e apresentou três soluções eficazes: usar uma lista auxiliar, iterar sobre uma cópia da lista e usar o Iterator de forma explícita. Sua análise de quando usar cada abordagem, com exemplos práticos, é muito valiosa para qualquer um que busca escrever código Java robusto.
Considerando que "o uso explícito do Iterator permite remover elementos de forma segura durante a iteração", qual você diria que é o maior benefício para um desenvolvedor ao utilizar o Iterator para remover um elemento de uma lista, em termos de eficiência e prevenção de bugs, em vez de usar um laço for-each para a remoção?