Подтвердить что ты не робот

В Java, можете ли вы изменить список во время итерации через него?

Я понимаю, что в Java a Collection<E> не следует изменять во время итерации через него, например, удаление или добавление элементов. Но как насчет изменения элементов в Списке? Например, что, если мы имеем

List<String> letters = new ArrayList<String>();
letters.add("A");
letters.add("B");
letters.add("C");
int i = 0;

for (String letter : letters) {
    letters.set(i, "D");
    i++;
}

Итак, я не говорю об изменении объекта, хранящегося в элементе; Я говорю об изменении того, что объект. Размер списка не изменяется, но объект в индексе изменяется, поэтому технически список изменяется. Мой босс утверждает, что этот код в порядке (и, похоже, он работает), но я все еще не думаю, что это правильно. Будет ли другой способ сделать это, возможно, используя метод set (E e) ListIterator, лучше?

4b9b3361

Ответ 1

Нет ничего плохого в идее изменения элемента внутри списка во время его перемещения (не изменяйте сам список, который не рекомендуется), но он может быть лучше выражен следующим образом:

for (int i = 0; i < letters.size(); i++) {
    letters.set(i, "D");
}

В конце весь список будет иметь букву "D" в качестве ее содержимого. Не рекомендуется использовать расширенный цикл for в этом случае, вы не используете переменную итерации ни для чего, кроме того, вы не можете изменять содержимое списка с помощью переменной итерации.

Обратите внимание, что приведенный выше фрагмент не изменяет структуру списка - это означает: никакие элементы не добавляются и не удаляются, а размер списков остается постоянным. Просто замена одного элемента на другой не считается структурной модификацией. Здесь ссылка к документации, цитируемой @ZouZou в комментариях, говорится, что:

Структурная модификация - это любая операция, которая добавляет или удаляет один или несколько элементов или явно изменяет размер массива поддержки; просто установка значения элемента не является структурной модификацией

Ответ 2

Используйте CopyOnWriteArrayList
и если вы хотите удалить его, выполните следующие действия:

for (Iterator<String> it = userList.iterator(); it.hasNext() ;)
{
    if (wordsToRemove.contains(word))
    {
        it.remove();
    }
}