Почему iterator.forEachRemaining не удаляет элемент в лямбде-приемнике?
Давайте посмотрим на этот пример:
public class ListIteratorTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("element1");
list.add("element2");
list.add("element3");
list.add("element4");
ListIterator<String> iterator = list.listIterator();
}
}
И теперь, это работает отлично:
// prints elements out, and then appropriately removes one after another
while (iterator.hasNext()){
System.out.println(iterator.next());
iterator.remove();
}
в то время как это вызывает исключение IllegalStateException:
// throws IllegalStateException, why?
iterator.forEachRemaining(n -> {
System.out.println(n);
iterator.remove();
});
У меня короткий вопрос: почему?
1 ответ
Обновлено благодаря @studro. Смотрите его комментарий ниже.
Документация API гласит:
Поведение итератора не определено, если базовая коллекция изменена во время выполнения итерации, кроме как путем вызова этого метода.
Кажется, что часть "неопределенное поведение" также применяется во время этой внутренней итерации.
Конечно, документация для forEachRemaining
утверждает, что поведение эквивалентно
while (hasNext())
action.accept(next());
и если action::accept
действительно звонил iterator.remove()
приведенный фрагмент не должен выдавать никаких исключений (если remove
является поддерживаемой операцией). Это может быть ошибка документации.