Hay muchas formas de atravesar y eliminar elementos en la lista o el mapa, y surgirán problemas cuando se usen de manera incorrecta. Aprendamos de este artículo a continuación.
1. Eliminar elementos durante la lista de transversal
Utilice el Traversal de Subínsro de índice
Ejemplo: Eliminar 2 en la lista
public static void main (string [] args) {list <integer> list = new ArrayList <Integer> (); 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 de salida:
1234List = [1, 2, 3, 4]
pregunta:
El resultado muestra que solo se eliminó un 2, y se perdió el otro 2. La razón es: después de eliminar los primeros 2, el número de elementos en el conjunto se reduce en 1, y los elementos posteriores se avanzan en 1 bit, lo que resulta en que se pierda el segundo 2.
Cómo usar para el recorrido de bucle
Ejemplo:
public static void listIterator2 () {list <Integer> list = new ArrayList <Integer> (); list.add (1); list.add (2); list.add (2); list.add (3); list.add (4); for (int value: list) {if (2 == valor) {list.remove (valor); } System.out.println (valor); } System.out.println (valor); } System.out.println ("list =" + list.ToString ()); }resultado:
Excepción en el hilo "principal" 12java.util.concurrentModificationException en java.util.arrayList $ ittr.checkforComodification (fuente desconocida) en java.util.arraylist $ ittr.next (fuente desconocida) en test.listiterator.listiteratorator2 (listiter.java:39) en test.listiterator.main (listiteratorator.sistIterator2 (listiter.Java:39) en test.listiterator.main (listiteratoratoratator:10
ilustrar:
Descripción de concurrenteModificationException en JDK:
public class ConcurrentModificationException extends
RuntimeException Esta excepción se arroja cuando el método detecta la modificación concurrente del objeto, pero no permite dicha modificación.
Por ejemplo, cuando un hilo itera en una colección, generalmente no se permite que se realicen otra modificación lineal. Por lo general, en estos casos, los resultados de la iteración son inciertos. Si se detecta este comportamiento, algunas implementaciones de iterador (incluidas todas las implementaciones de la colección general proporcionadas por JRE) pueden optar por lanzar esta excepción. El iterador que realiza esta operación se llama iterador de falla rápida porque el iterador falla muy rápidamente sin arriesgar el riesgo de un comportamiento incierto arbitrario en algún momento en el futuro.
Nota : Esta excepción no siempre indica que el objeto ha sido modificado simultáneamente por un hilo diferente. Si un solo hilo emite una secuencia de llamadas de método que viola el contrato del objeto, el objeto puede lanzar esta excepción. Por ejemplo, si un hilo modifica directamente la colección cuando itera en la colección usando un iterador de falla rápida, el iterador lanzará esta excepción.
Nota : El comportamiento de falla rápida del iterador no puede garantizarse, porque en general, es imposible hacer garantías difíciles sobre si hay modificaciones concurrentes fuera de sincronas. Una operación de falla rápida hará todo lo posible para lanzar ConcurrentModificationException . Por lo tanto, está mal escribir un programa que depende de esta excepción para mejorar la corrección de tales operaciones. La forma correcta es: ConcurrentModificationException debe usarse solo para detectar errores.
Para cada uno en Java realmente usa Iterator para el procesamiento. El iterador no permite eliminar las colecciones durante el uso del iterador. Esto hace que el iterador arroje ConcurrentModificationException .
El camino correcto
Ejemplo:
public static void listIterator3 () {list <integer> list = new ArrayList <Integer> (); list.add (1); list.add (2); list.add (2); list.add (3); list.add (4); Iterador <integer> 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. Eliminar elementos durante el traversal del mapa
Ejemplos de enfoque correcto:
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"); // Traversal completo de MAP para (Entrada <String, String> Entry: MAP.ENTRYSET ()) {System.out.printf ("Key: %s valor: %s/r/n", entry.getkey (), entry.getValue ()); } // Eliminar el elemento iterador <map.entry <string, string >> it = map.entryset (). Iterator (); while (it.hasnext ()) {map.entry <string, string> entry = it.next (); Clave de cadena = Entry.getKey (); int k = Integer.ParseInt (clave); if (k%2 == 1) {System.out.printf ("Eliminar la clave:%s valor:%s/r/n", key, entry.getValue ()); it.remove (); }} // mapa transversal completo para (entrada <string, string> Entry: map.entryset ()) {System.out.printf ("clave: %s valor: %s/r/n", entry.getkey (), entry.getValue ()); }}resultado:
Clave: 1 Valor: Test1Key: 2 Valor: Test2Key: 3 Valor: Test3Key: 4 Valor: Test4Delete Clave: 1 Valor: Test1Delete Clave: 3 Valor: Test3Key: 2 Valor: Test2Key: 4 Valor: Test4
Aviso
Pero también hay cosas a las que debemos prestar atención sobre remove() del iterador:
El método remove() iterator.next() ().
Antes de llamar al método remove() , next() debe llamarse una vez.
Descripción del método remove () en JDK-API:
void remove() elimina el último elemento devuelto por el iterador del iterador apuntado por el iterador (operación opcional). Este método solo se puede llamar una vez por llamada siguiente. Si el iterador se modifica de una manera que no sea llamar a este método al iterar, el comportamiento del iterador es ambiguo.
Lanzamientos: UnsupportedOperationException : si el iterador no admite remove la operación. IllegalStateException : si no se ha llamado al next método, o se ha llamado al método remove después de la última llamada al next método.
Resumir
Lo anterior se trata de eliminar elementos durante el recorrido de la lista y el mapa. Espero que el contenido de este artículo sea de ayuda para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse.