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

E se usar um break no laço?

Foi dito que não pode fazer o laço e alterar a ArrayList ao mesmo tempo mas com um break funciona. Seria mais eficiente que usar o Iterator?

public void removeEmpresa(Integer idEmpresa) {
        for (Empresa empresa : listaEmpresas) {
            if (empresa.getId() == idEmpresa) {
                listaEmpresas.remove(empresa);
                break;
            }
        }
    }
2 respostas
solução!

Opa José, tudo tranquilo?

Não vou mentir que essa é a primeira vez que vi alguém usar o break nesse contexto e eu nem imaginava que isso poderia dar certo! Mas enfim, peço perdão caso eu não consiga esclarecer todos os pontos por conta disso, mas vamos lá! :D

A motivação por trás da ConcurrentModificationException é evitar que alterações não permitidas sejam feitas em cima de uma coleção, o que é o caso de alterações na lista no meio da iteração. Quando você usou o break, a modificação não pode ser detectada já que assim que o elemento foi encontrado, nós imediatamente saímos do laço sem que o iterador perceba que ocorreu uma violação nas regras do objeto.

Se formos até a documentação da exception, vemos que as violações que ela busca evitar está relacionada à modificações que poderiam causar resultados inesperados após a iteração, principalmente se estivermos trabalhando com programação paralela onde uma thread pode acabar alterando a coleção enquanto outra está no meio da iteração.

Então veja que o uso do break é quase que uma gambiarra para evitar que a ConcurrentModificationException seja lançada, assim como algumas pessoas fazem a iteração do for ao contrário pois isso também funciona quando lidamos com ArrayList.

Finalizando, o motivo para eu não concordar com a eficiência do break em relação ao Iterator - embora nesse caso específico possa ser verdade, está no fato de que caso estivéssemos em uma situação onde mesmo após removermos o elemento, precisássemos continuar com a iteração para realizar qualquer outra ação, nós não conseguiríamos.

Espero ter ajudado. Se ficou alguma dúvida é só avisar!

Bons estudos!!

A minha motivação ao usar o break foi de evitar ficar realizando a iteração desnecessariamente caso a empresa em questão fosse encontrada. Entendo a questão da eficiência. Nesse caso realmente eu não tenho interesse em continuar executando a iteração. Em relação à ConcurrentModificationException , a mesma não ocorre ao usar a LinkedList. Ela aparece ao tentar remover sempre o último elemento da lista:

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at br.com.alura.gerenciador.modelo.BancoDados.removeEmpresa(BancoDados.java:36)

Na linha 36:

Empresa empresa = it.next();

O mesmo não ocorre ao usar a LinkedList.

Um abraço !!