Есть много способов пройти и удалять элементы в списке или карте, и возникают проблемы при неправильном использовании. Давайте поучимся из этой статьи ниже.
1. Удалить элементы во время пересечения списка
Используйте индекс индексного подписания
Пример: удалить 2 в списке
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 ()); }Результат вывода:
1234list = [1, 2, 3, 4]
вопрос:
Результат показывает, что только один 2 был удален, а остальные 2 были пропущены. Причина в том, что после удаления первых 2 количество элементов в наборе уменьшается на 1, а последующие элементы перемещаются вперед на 1 бит, что приводит к пропущению второго 2.
Как использовать для прохождения петли
Пример:
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 == value) {list.remove (value); } System.out.println (значение); } System.out.println (значение); } System.out.println ("list =" + list.toString ()); }результат:
Исключение в потоке "Main" 12Java.Util.concurrentModificationException at java.util.arraylist $ ittr.checkforcomodification (неизвестный источник) на java.util.arraylist $ ittr.next (неизвестный источник) на test.listiterator.listiterator2 (listicerator.java:39) at test.listitrator.
иллюстрировать:
Описание concurrentModificationException в JDK:
public class ConcurrentModificationException extends
Runtimeexception Это исключение бросается, когда метод обнаруживает одновременную модификацию объекта, но не допускает такую модификацию.
Например, когда поток итерации на коллекции, обычно не допускается еще одна линейная модификация. Обычно в этих случаях результаты итерации неясны. Если это поведение обнаружено, некоторые реализации итератора (включая все общие реализации коллекции, предоставленные JRE) могут выбрать это исключение. Итератор, который выполняет эту операцию, называется итератором быстрого сбоя, потому что итератор терпит неудачу очень быстро, не рискуя риску произвольного неопределенного поведения в будущем.
Примечание . Это исключение не всегда указывает на то, что объект был изменен одновременно другим потоком. Если один поток выдает последовательность вызовов метода, которая нарушает контракт объекта, объект может бросить это исключение. Например, если поток непосредственно изменяет коллекцию, когда итерация в коллекции, используя итератор Fast Fail, итератор выбросит это исключение.
Примечание . Быстрое поведение итератора не может быть гарантировано, потому что, как правило, невозможно сделать какие-либо жесткие гарантии, есть ли какие-либо не-синхронные параллельные модификации. Быстрая операция по сбое сделает все возможное, чтобы бросить ConcurrentModificationException . Следовательно, неправильно писать программу, которая зависит от этого исключения, чтобы улучшить правильность таких операций. Правильным способом является: ConcurrentModificationException следует использовать только для обнаружения ошибок.
Для каждого в Java фактически используется итератор для обработки. Итератор не позволяет удалять коллекции во время использования итератора. Это заставляет итератор бросить ConcurrentModificationException .
Правильный путь
Пример:
public static void listicerator3 () {list <Integer> list = new ArrayList <Integer> (); list.add (1); list.add (2); list.add (2); list.add (3); list.add (4); Итератор <Integer> it = list.iterator (); while (it.hasnext ()) {integer value = it.next (); if (2 = value) {it.remove (); } System.out.println (значение); } System.out.println (значение); } System.out.println ("list =" + list.toString ()); }результат:
12234list = [1, 3, 4]
2. Удалить элементы во время обхода карты
Примеры правильного подхода:
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"); // Полный обход карты для (entry <string, string> intpirt: map.entryset ()) {system.out.printf ("key: %s Значение: %s/r/n", entry.getkey (), intry.getValue ()); } // Удалить элемент итератор <map.Entry <String, String >> it = map.EntrySet (). Iterator (); while (it.hasnext ()) {map.entry <string, string> entry = it.next (); String key = entry.getKey (); int k = integer.parseint (key); if (k%2 == 1) {System.out.printf ("Удалить ключ:%s Значение:%s/r/n", key, entry.getValue ()); it.remove (); }} // Полная карта Traverse для (entry <string, string> intry: map.entryset ()) {system.out.printf ("key: %s Значение: %s/r/n", entry.getKey (), intry.getValue ()); }}результат:
Ключ: 1 Значение: Test1Key: 2 Значение: Test2Key: 3 Значение: TEST3Key: 4 Значение: TEST4DELETE КЛЮЧ: 1 Значение: TEST1DELETE Ключ: 3 Значение: TEST3Key: 2 Значение: TEST2Key: 4 Значение: TEST4
Уведомление
Но есть и вещи, на которые нам нужно обратить внимание на метод remove() итератора:
Метод remove() iterator.next() ().
Перед вызовом метода remove() метод next() должен быть вызван один раз.
Описание метода rement () в JDK-API:
void remove() Удаляет последний элемент, возвращаемый итератором из коллекции, на который указан итератор (дополнительная операция). Этот метод может быть вызван только один раз за вызов следующим образом. Если итератор изменен таким образом, кроме того, что вызывает этот метод при итерации, поведение итератора неоднозначно.
Выбросы: UnsupportedOperationException - если итератор не поддерживает операцию remove . IllegalStateException - если next метод не был вызван, или метод remove был вызван после последнего вызова next метода.
Суммировать
Выше приведено все о удалении элементов во время прохождения списка и карты. Я надеюсь, что содержание этой статьи поможет для каждого обучения или работы каждого. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения.