Como corrigir ConcurrentModificationException ao iterar sobre uma lista?

ConcurrentModificationException ocorre quando uma coleção é modificada enquanto está sendo percorrida por um iterador.

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.

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

Compartilhe este tutorial: Como corrigir ConcurrentModificationException ao iterar sobre uma lista

Compartilhe este tutorial

Continue aprendendo:

O que causa OutOfMemoryError e como evitar esse problema

OutOfMemoryError ocorre quando a JVM não consegue alocar mais memória para a execução do programa, causando uma falha de execução.

Tutorial anterior

O que significa UnsupportedOperationException e como tratar esse erro

UnsupportedOperationException ocorre quando tentamos executar uma operação que não é suportada por um objeto ou método específico.

Próximo tutorial