Existem muitas maneiras de atravessar e excluir elementos na lista ou mapa, e os problemas surgirão quando usados incorretamente. Vamos aprender com este artigo abaixo.
1. Exclua elementos durante a travessia da lista
Use o Índice Subscript Traversal
Exemplo: Exclua 2 na lista
public static void main (string [] args) {list <Teger> list = new ArrayList <Teger> (); list.add (1); list.add (2); list.add (2); list.add (3); list.add (4); for (int i = 0; i <list.size (); i ++) {if (2 == list.get (i)) {list.remove (i); } System.out.println (list.get (i)); } System.out.println ("list =" + list.toString ()); }Resultado da saída:
1234List = [1, 2, 3, 4]
pergunta:
O resultado mostra que apenas um 2 foi excluído e os outros 2 foram perdidos. O motivo é: depois de excluir os 2 primeiros, o número de elementos no conjunto é reduzido por 1 e os elementos subsequentes são movidos em frente em 1 bit, resultando na falta dos segundos 2.
Como usar para travessia de loop
Exemplo:
public static void listiterator2 () {list <Teger> list = new ArrayList <Teger> (); list.add (1); list.add (2); list.add (2); list.add (3); list.add (4); for (int valor: list) {if (2 == value) {list.remove (value); } System.out.println (valor); } System.out.println (valor); } System.out.println ("list =" + list.toString ()); }resultado:
Exceção em thread "main" 12java.util.ConcurrentModificationException em java.util.arraylist $ ittr.checkforComodification (fonte desconhecida) em java.util.arraylist $ ittr.next (fonte desconhecida) em test.listiterator.listiterator2 (listiterator.java na test.listiterator.main (listiterator.java:10)
ilustrar:
Descrição da ConcurrentModificationException no JDK:
public class ConcurrentModificationException extends
RUNTimeException Esta exceção é lançada quando o método detecta modificação simultânea do objeto, mas não permite essa modificação.
Por exemplo, quando um thread itera em uma coleção, outra modificação linear geralmente não pode ser feita. Geralmente nesses casos, os resultados da iteração são incertos. Se esse comportamento for detectado, algumas implementações do iterador (incluindo todas as implementações gerais de coleção fornecidas pelo JRE) poderão optar por lançar essa exceção. O iterador que executa esta operação é chamado de iterador de falha rápida porque o iterador falha muito rapidamente, sem arriscar o risco de comportamento incerto arbitrário em algum momento no futuro.
Nota : Esta exceção nem sempre indica que o objeto foi modificado simultaneamente por um encadeamento diferente. Se um único thread emitir uma sequência de chamadas de método que viole o contrato do objeto, o objeto poderá lançar essa exceção. Por exemplo, se um thread modificar diretamente a coleção quando itera na coleção usando um iterador de falha rápido, o iterador lançará essa exceção.
NOTA : O comportamento de falha rápida do iterador não pode ser garantida, porque geralmente é impossível fazer garantias difíceis sobre se existem modificações simultâneas fora do síncrono. Uma operação de falha rápida fará o possível para lançar ConcurrentModificationException . Portanto, é errado escrever um programa que depende dessa exceção para melhorar a correção de tais operações. A maneira correta é: ConcurrentModificationException deve ser usado apenas para detectar erros.
Para cada um em Java, na verdade, usa o iterador para processamento. O iterador não permite que as coleções sejam excluídas durante o uso do iterador. Isso faz com que o iterador jogue ConcurrentModificationException .
Do jeito certo
Exemplo:
public static void listiterator3 () {list <Teger> list = new ArrayList <Teger> (); list.add (1); list.add (2); list.add (2); list.add (3); list.add (4); Iterator <Teger> it = list.iterator (); while (it.hasnext ()) {integer value = it.Next (); if (2 == valor) {it.remove (); } System.out.println (valor); } System.out.println (valor); } System.out.println ("list =" + list.toString ()); }resultado:
12234List = [1, 3, 4]
2. Exclua elementos durante o travessal do mapa
Exemplos de abordagem correta:
public static void main (string [] args) {hashmap <string, string> map = new hashmap <string, string> (); map.put ("1", "test1"); map.put ("2", "test2"); map.put ("3", "test3"); map.put ("4", "test4"); // Travessal completo do mapa para (entrada <string, string> Entrada: map.entrySet ()) {System.out.printf ("chave: %s valor: %s/r/n", entrada.getKey (), entrada.getValue ()); } // exclua o elemento iterador <pap.entry <string, string >> it = map.entrySet (). Iterator (); while (it.hasnext ()) {map.entry <string, string> entradas = it.next (); String key = Entry.getKey (); int k = integer.parseint (chave); if (k%2 == 1) {System.out.printf ("Chave de exclusão:%s Valor:%s/r/r/n", chave, entrada.getValue ()); it.remove (); }} // mapa de travessia completo para (entrada <string, string> entrada: map.entrySet ()) {System.out.printf ("key: %s valor: %s/r/n", entrada.getKey (), entrada.getValue ()); }}resultado:
Chave: 1 Valor: Test1Key: 2 Valor: Test2Key: 3 Valor: Test3Key: 4 Valor: Test4Delete Tecla: 1 Valor: Test1Delete Tecla: 3 Valor: Test3Key: 2 Valor: Test2Key: 4 Valor: Test4
Perceber
Mas também há coisas em que precisamos prestar atenção no método remove() do iterador:
O método remove() iterator.next() () é chamado.
Antes de ligar para o método remove() , next() deve ser chamado uma vez.
Descrição do método Remone () no JDK-API:
void remove() remove o último elemento retornado pelo iterador da coleção apontada para o iterador (operação opcional). Este método só pode ser chamado uma vez por chamada em seguida. Se o iterador for modificado de uma maneira que não seja chamar esse método ao itera, o comportamento do iterador será ambíguo.
Lances: UnsupportedOperationException - Se o iterador não suportar a operação remove . IllegalStateException - Se o next método não tiver sido chamado, ou o método remove foi chamado após a última chamada para o next método.
Resumir
O exposto acima é sobre excluir elementos durante a travessia da lista e do mapa. Espero que o conteúdo deste artigo seja de ajuda para estudar ou trabalhar de todos. Se você tiver alguma dúvida, pode deixar uma mensagem para se comunicar.