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

Как добавить элемент в список во время итерации в java?

Скажем, у меня есть список вроде:

List<String> list = new ArrayList<>();
list.add("a");
list.add("h");
list.add("f");
list.add("s");

При повторении этого списка я хочу добавить элемент в конце списка. Но я не хочу итерации по вновь добавленным элементам, которые я хочу перебирать до начального размера списка.

for (String s : list)
     /* Here I want to add new element if needed while iterating */

Кто-нибудь может предложить мне, как я могу это сделать?

4b9b3361

Ответ 1

Вы не можете использовать для этого инструкцию foreach. В foreach используется внутренний итератор:

Итераторы, возвращаемые этим классом итератором и listIterator методы не работают быстро: если список структурно модифицирован в любом время после создания итератора, любым способом, за исключением итератор самостоятельно удаляет или добавляет методы, итератор будет бросать ConcurrentModificationException.

(из ArrayList javadoc)

В инструкции foreach у вас нет доступа к методу добавления итератора и в любом случае, который еще не является типом добавления, который вы хотите, потому что он не добавляется в конце. Вам нужно будет перемещать список вручную:

int listSize = list.size();
for(int i = 0; i < listSize; ++i)
  list.add("whatever");

Обратите внимание, что это эффективно только для списков, допускающих произвольный доступ. Вы можете проверить эту функцию, проверив, реализует ли этот список интерфейс маркера RandomAccess. ArrayList имеет произвольный доступ. Связанный список не работает.

Ответ 2

Просто повторите старомодный способ, потому что вам нужна явная обработка индексов:

List myList = ...
...
int length = myList.size();
for(int i = 0; i < length; i++) {
   String s = myList.get(i);
   // add items here, if you want to
}

Ответ 4

Вы можете выполнить итерацию копии (клона) вашего исходного списка:

List<String> copy = new ArrayList<String>(list);
for (String s : copy) {
    // And if you have to add an element to the list, add it to the original one:
    list.add("some element");
}

Обратите внимание, что даже при добавлении нового элемента в список нельзя добавлять новый элемент, потому что это приведет к ConcurrentModificationException.

Ответ 5

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

Представьте, что произойдет, когда исходный список OP содержит несколько миллионов элементов; какое-то время вы будете всасывать вдвое больше памяти.

В дополнение к сохранению ресурсов этот метод также мешает нам прибегать к циклам стиля 80-х и использовать то, что является эффективным индексом массива, который может быть непривлекательным в некоторых случаях.