Здесь есть два вопроса:
Первая проблема заключается в добавлении к Collection
после возврата Iterator
. Как уже упоминалось, при изменении базового Collection
не существует определенного поведения, как отмечено в документации для Iterator.remove
:
... Поведение итератора
не указано, если основной
коллекция модифицируется в то время как
итерация выполняется в любом случае
кроме вызова этого метода.
Второй вопрос: даже если можно получить Iterator
и затем вернуться к тому же элементу, в котором находился Iterator
, нет никакой гарантии относительно порядка итерации, как отмечено в Collection.iterator
документация по методу:
... Нет никаких гарантий относительно
порядок, в котором элементы
возвращается (если эта коллекция не является
экземпляр некоторого класса, который обеспечивает
гарантия).
Например, допустим, у нас есть список [1, 2, 3, 4]
.
Скажем, 5
было добавлено, когда Iterator
было в 3
, и каким-то образом мы получили Iterator
, который может возобновить итерацию с 4
. Однако нет гарантии, что 5
придет после 4
. Порядок итерации может быть [5, 1, 2, 3, 4]
- тогда итератор все равно пропустит элемент 5
.
Поскольку поведение не гарантировано, нельзя предполагать, что все произойдет определенным образом.
Одной из альтернатив может быть отдельный Collection
, к которому могут быть добавлены вновь созданные элементы, а затем итерации по этим элементам:
Collection<String> list = Arrays.asList(new String[]{"Hello", "World!"});
Collection<String> additionalList = new ArrayList<String>();
for (String s : list) {
// Found a need to add a new element to iterate over,
// so add it to another list that will be iterated later:
additionalList.add(s);
}
for (String s : additionalList) {
// Iterate over the elements that needs to be iterated over:
System.out.println(s);
}
Редактировать
Обработка Ответ Ави , можно поставить в очередь элементы, которые мы хотим перебрать в очередь, и удалить элементы, пока в очереди есть элементы. Это позволит «перебирать» новые элементы в дополнение к исходным.
Давайте посмотрим, как это будет работать.
Концептуально, если в очереди есть следующие элементы:
[1, 2, 3, 4]
И когда мы удаляем 1
, мы решаем добавить 42
, очередь будет выглядеть следующим образом:
[2, 3, 4, 42]
Поскольку очередь представляет собой структуру данных FIFO (первый-первый-первый-выходной), такое упорядочение является типичным. (Как отмечено в документации для интерфейса Queue
, в этом нет необходимости Queue
. Возьмем случай PriorityQueue
, который упорядочивает элементы по их естественному порядок, так что это не FIFO.)
Ниже приведен пример использования LinkedList
(то есть Queue
) для прохождения всех элементов вместе с дополнительными элементами, добавленными во время декуинга. Как и в примере выше, элемент 42
добавляется при удалении элемента 2
:
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(1);
queue.add(2);
queue.add(3);
queue.add(4);
while (!queue.isEmpty()) {
Integer i = queue.remove();
if (i == 2)
queue.add(42);
System.out.println(i);
}
Результат следующий:
1
2
3
4
42
Как и следовало ожидать, появился элемент 42
, который был добавлен, когда мы нажали 2
.