При удалении изнутри foreach, мы должны сделать шаг назад - PullRequest
7 голосов
/ 17 мая 2010

Возьмите этот код Java:

for (ContactsReduced curContact : allcontacts) {
 ..........
 allcontacts.remove(curContact);
}

Я делаю на основе условия удаление, будет ли foreach пропускать следующий элемент по порядку, и нужно ли нам как-то отступать?

Ответы [ 5 ]

8 голосов
/ 17 мая 2010

Этот код не работает с большинством коллекций - кроме нескольких коллекций, таких как в java.util.concurrent, изменение коллекции при ее повторении не поддерживается.

Несколько вариантов:

  • Получите и используйте итератор в явном виде (вызовите iterator() в коллекции) вместо расширенного цикла for и вызовите iterator.remove(), чтобы удалить элемент
  • Используйте плоскость для петли, либо двигаясь вперед и отступая после снятия, либо двигаясь назад от конца
  • Вести отдельный список элементов для удаления, а затем удалить их после итерации
3 голосов
/ 17 мая 2010

Взгляните на раздел об итераторах в руководстве по интерфейсу коллекции

Используйте Iterator вместо конструкции for-each, когда вам нужно удалить текущий элемент. Конструкция for-each скрывает итератор, поэтому вы не можете вызвать remove. Поэтому конструкция for-each непригодна для фильтрации.

Обратите внимание, что Iterator.remove - единственный безопасный способ изменить коллекцию во время итерации

1 голос
/ 17 мая 2010
List<Integer> al = new ArrayList<Integer>();
for(int i=0;i<10;i++){
  al.add(i);
}
for(Integer x:al){
  al.remove(x);
  System.out.println(al);
}

Ну, вопрос интересный, поэтому я попробовал его в своей системе, и вот что я получил.

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
    at java.util.AbstractList$Itr.next(Unknown Source)
    at test.Main.main(Main.java:17)
0 голосов
/ 17 мая 2010

Итератор завершится с ошибкой ConcurrentModificationException. Так устроен каркас коллекции.

0 голосов
/ 17 мая 2010

Определенно не рекомендуется вмешиваться в коллекцию при ее повторении. Я не уверен, что Java это позволяет; это может вызвать исключение. Я знаю, что C # делает ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...