Ответ
Объект Stream в Java можно использовать только один раз. После выполнения терминальной операции поток считается потребленным и закрывается.
Почему? Потоки предназначены для одноразовой обработки данных из источника. Они не хранят элементы, а предоставляют их по мере необходимости.
Пример ошибки повторного использования:
Stream<String> stream = Stream.of("A", "B", "C");
long count = stream.count(); // Терминальная операция
stream.forEach(System.out::println); // IllegalStateException: stream has already been operated upon or closed
Как правильно обрабатывать данные несколько раз?
- Создавать новый поток из исходного источника данных:
List<String> list = Arrays.asList("A", "B", "C"); list.stream().forEach(System.out::println); // OK list.stream().count(); // OK — это новый поток - Использовать поставщика (Supplier) потоков:
Supplier<Stream<String>> streamSupplier = () -> Stream.of("A", "B", "C"); streamSupplier.get().forEach(System.out::println); // OK streamSupplier.get().count(); // OK — каждый get() создает новый поток
Вывод: Поток — это не контейнер данных, а инструмент для их однократной обработки. Для повторных операций необходимо обращаться к источнику данных.