Ответ 1
Посмотрели ли вы на исходный код, как эти классы реализованы?
Метод sorted()
сделает копию вашего списка для сортировки.
Таким образом, он ведет себя по-другому: вы выполняете итерацию по отсортированной копии, но удаляете только из первого списка.
peek() не рекомендуется
Метод peek
не рекомендуется использовать; из JavaDoc:
Этот метод существует главным образом для поддержки отладки
Вполне возможно поставить System::println
там или аналогичный для целей разработки, но это не функциональность, которую вы должны использовать для своей окончательной программы.
Никогда не пытайтесь изменить текущий поток
Прочитайте спецификацию API пакета потока:
https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#NonInterference
Для большинства источников данных предотвращение помех означает , гарантируя, что источник данных вообще не будет изменен во время выполнения конвейера потока.
Итак, другими словами: вам не удастся удалить из списка, который вы сейчас используете, нет гарантий, что он будет работать.
Что происходит
Ваш начальный список
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] pos = 0
Вы печатаете 0
и удаляете его, затем переходите к следующей позиции. Новый массив тогда
[1, 2, 3, 4, 5, 6, 7, 8, 9, null] pos = 1
В следующей позиции теперь значение 2
, поэтому распечатайте и удалите 2
:
[1, 3, 4, 5, 6, 7, 8, 9, null, null] pos = 2
и т.д. Проблема состоит в том, что из-за ваших одновременных удалений оставшаяся часть списка продолжает двигаться вперед.
ConcurrentModificationException
бросается в конец потока. Это похоже на решение о производительности (только один раз для одновременных изменений, а не на каждой итерации) только для forEachRemaining
, поэтому этот поток не работает быстро