Документация по API не дает такой гарантии, что «последующие операции больше не работают с резервной коллекцией», следовательно, вы никогда не должны полагаться на такое поведение конкретной реализации.
В вашем примере происходитжелаемая вещь случайно;нет даже гарантии, что List
, созданный collect(Collectors.toList())
, поддерживает операцию remove
.
Чтобы показать контрпример
Set<Integer> set = IntStream.range(0, 10).boxed()
.collect(Collectors.toCollection(TreeSet::new));
set.stream()
.filter(i -> i > 5)
.sorted()
.forEach(set::remove);
, выдает ConcurrentModificationException
.Причина в том, что реализация оптимизирует этот сценарий, так как источник уже отсортирован.В принципе, он мог бы выполнить ту же оптимизацию для вашего исходного примера, поскольку forEach
явно выполняет действие в не указанном порядке, следовательно, сортировка не требуется.
Существуют другие возможные оптимизации, например sorted().findFirst()
может быть преобразован в операцию «найти минимум», без необходимости копировать элемент в новое хранилище для сортировки.
Таким образом, суть в том, что, полагаясь на неопределенное поведение, что может сработатьсегодня может наступить завтра, когда будут добавлены новые оптимизации.