Como o mapa do contêiner em Java:
for(Pessoa pessoa: pList){
if(person.getGender()==Gênero.MALE){
pList.remove(person); //A operação de remoção não pode ser executada durante a travessia.
}
}
Ao percorrer um mapa, ele geralmente obtém o conjunto de seus valores-chave e, em seguida, usa um iterador para percorrer o mapa.
Observe que durante o processo de travessia, apenas os elementos do Mapa podem ser processados adequadamente. Os elementos do Mapa não podem ser adicionados ou reduzidos. Em outras palavras, o tamanho do Mapa não pode ser alterado e ocorrerá uma exceção (não poderá ser usado durante o processo). processo de travessia). modificar, excluir ou adicionar elementos no mapa)
A exceção relatada é a exceção java.util.ConcurrentModificationException
classe pública ConcurrentModificationException estende RuntimeException
Esta exceção é lançada quando um método detecta modificação simultânea de um objeto, mas não permite tal modificação.
Por exemplo, enquanto um thread está iterando em uma coleção, outro thread normalmente não tem permissão para modificar linearmente a coleção. Muitas vezes, nestes casos, os resultados da iteração não são claros. Algumas implementações de iteradores (incluindo todas as implementações de coleção genérica fornecidas pelo JRE) podem optar por lançar esta exceção se este comportamento for detectado. Os iteradores que executam esta operação são chamados de iteradores fail-fast porque o iterador falha completamente rapidamente, sem arriscar um comportamento arbitrário não especificado em algum momento no futuro.
Observe que esta exceção nem sempre indicará que o objeto foi modificado simultaneamente por diferentes threads. Um objeto pode lançar essa exceção se um único thread emitir uma sequência de chamadas de método que viole o contrato do objeto. Por exemplo, se um thread modificar diretamente uma coleção enquanto itera sobre ela usando um iterador rápido, o iterador lançará essa exceção.
Observe que o comportamento fail-fast dos iteradores não é garantido porque, em geral, não é possível dar quaisquer garantias concretas sobre se ocorrerão modificações simultâneas não sincronizadas. Operações com falha rápida lançam uma ConcurrentModificationException com base no melhor esforço. Portanto, é um erro escrever um programa que dependa desta exceção para melhorar a correção de tais operações. A abordagem correta é: ConcurrentModificationException deve ser usada apenas para detectar bugs.
Ao tentar modificar diretamente o conteúdo de uma Coleção/Mapa enquanto usa um iterador rápido para iterar sobre uma Coleção ou Mapa, uma exceção java.util.ConcurrentModificationException será lançada mesmo quando executado em um único encadeamento.
O Iterator funciona em um thread separado e possui um bloqueio mutex. Após a criação do Iterador, uma tabela de índice de link único apontando para o objeto original será estabelecida. Quando o número de objetos originais for alterado, o conteúdo desta tabela de índice não será alterado de forma síncrona, portanto, quando o ponteiro do índice se mover para trás, ele não poderá ser alterado. ser encontrado para iterar o objeto, portanto, de acordo com o princípio fail-fast, o Iterator lançará imediatamente uma exceção java.util.ConcurrentModificationException.
Portanto, o Iterador não permite que o objeto iterado seja alterado enquanto estiver funcionando. Mas você pode usar o método remove() do próprio Iterator para excluir objetos. O método Iterator.remove() excluirá o objeto de iteração atual enquanto mantém a consistência do índice.
O interessante é que se o seu objeto Collection/Map realmente tiver apenas um elemento, a exceção ConcurrentModificationException não será lançada. É por isso que é apontado no javadoc: seria errado escrever um programa que dependesse desta exceção para sua correção: ConcurrentModificationException deve ser usado apenas para detectar bugs.