Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Estou com dúvida no curso de Design Patterns para bons programadores, no exercício do capítulo Comportamentos compostos por outros comportamentos e o Decorator.

Estou com um problema aqui, que não é nem referente ao padrão de projeto em si, mas em uma parte da implementação.

Essa parte do meu código esta errada, imagino eu: ```public List filtra(List contas) { Calendar dataAtual = Calendar.getInstance();

Iterator iterator = contas.iterator(); while (iterator.hasNext()) { Conta c2 = iterator.next(); if (c2.getDataCriacao().get(Calendar.MONTH) == dataAtual .get(Calendar.MONTH) && c2.getDataCriacao().get(Calendar.YEAR) == dataAtual .get(Calendar.YEAR)) contas.remove(c2);

}

return (filtro == null ? contas : filtro.filtra(contas)); }O problema se da na linhaConta c2 = iterator.next();``` Quando eu passo por esta lógica com alguma Conta criada neste mês, ele me da a exception java.util.ConcurrentModificationException. Eu pesquisei e sei que tem algo a ver com a iteração sobre a minha Lista... eu remover um objeto dela durante a iteração, algo assim. Mas não sei exatamente o porque. Alguem pode ajudar?

2 respostas

Parte do código que saiu fora da identação.

public List filtra(List contas) { 
Calendar dataAtual = Calendar.getInstance();

Iterator iterator = contas.iterator(); 
while (iterator.hasNext()) {
 Conta c2 = iterator.next(); 
 if (c2.getDataCriacao().get(Calendar.MONTH) == dataAtual .get(Calendar.MONTH) && c2.getDataCriacao().get(Calendar.YEAR) == dataAtual .get(Calendar.YEAR)) 
     contas.remove(c2);

}

return (filtro == null ? contas : filtro.filtra(contas)); }
solução!

Este é um problema bem recorrente, não só em java... O problema ocorre porque você altera a estrutura da collection sendo iterada (muda tamanho e indexações). Uma forma simples de resolver isso é na primeira "passada" marcar quem deve ser removido e depois efetivamente remove-los como explicitado a baixo:

public List filtra(List contas) { 
     List<Conta> contasARemover = new ArrayList<>();
     Calendar dataAtual = Calendar.getInstance();
     Iterator iterator = contas.iterator(); 
     while (iterator.hasNext()) {
         Conta c2 = iterator.next(); 
         if (c2.getDataCriacao().get(Calendar.MONTH) == dataAtual .get(Calendar.MONTH) && c2.getDataCriacao().get(Calendar.YEAR) == dataAtual .get(Calendar.YEAR)) 
            //Só guardamos a referencia (marcamos como candidato a remoção)
             contasARemover.add(c2);
     }

     //efetivamente removemos todos os marcados.
     contas.removeAll(contasARemover);

     return (filtro == null ? contas : filtro.filtra(contas)); }

Não testei o código a cima, mas teoricamente deve funcionar. Dúvidas nos dê uma resposta ;)