Есть две проблемы:
Первый вопрос, добавив к Collection
после Iterator
возвращаются. Как уже упоминалось, не существует определенное поведение, когда основной Collection
изменяется, как указано в документации на Iterator.remove
:
... Поведение итератора является неопределенные если основной набор изменяется в то время как итерация выполняется любым способом , кроме как путем вызова этого метода.
Вторая проблема, даже если Iterator
может быть получена, а затем вернуться к тому же элементу, Iterator
был в, нет никакой гарантии, о порядке iteratation, как указана в документации 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);
}
Редактировать
Конкретизируя Avi's answer, его можно поставить в очередь элементы, которые мы хотим перебрать в очередь, и удалить элементы, в то время как в очереди есть элементы. Это позволит «итерации» над новыми элементами в дополнение к исходным элементам.
Давайте посмотрим, как это будет работать.
Концептуально, если мы имеем следующие элементы в очереди:
[1, 2, 3, 4]
И, когда мы убираем 1
, мы решили добавить 42
, очередь будет как следующее:
[2, 3, 4, 42]
Поскольку очередь представляет собой структуру данных FIFO (first-in, first-out), этот заказ типичен. (Как отмечено в документации по интерфейсу Queue
, это не необходимость в Queue
. Возьмет случай PriorityQueue
, который упорядочивает элементы по их естественному порядку, так что это не FIFO.)
Ниже приведен пример использования a 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
.
Если кто-то хочет подробно остановиться на этой идее, не стесняйтесь ... – Avi
Это хороший способ сделать что-то, если оно подходит для модели, которую программирует OP. Таким образом, вы не используете итератор - просто цикл while. в то время как в очереди есть элементы, обработайте первый элемент. Однако вы можете сделать это и со списком. – Eddie
Не понимаю. – inetphantom