Ответ
Да, Stream по умолчанию является однопоточным (последовательным).
Поток становится параллельным только при явном вызове метода parallel().
Пример последовательного (однопоточного) Stream:
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
numbers.stream() // Создаёт последовательный поток
.map(n -> n * 2) // Операции выполняются в одном потоке
.forEach(System.out::println); // Порядок элементов гарантирован
Переключение режимов:
stream.parallel() // Переключает поток в параллельный режим
stream.sequential() // Возвращает поток в последовательный режим
Почему это важно:
- Последовательный поток предсказуем и прост для отладки.
- Параллельный поток (
parallel()) используетForkJoinPoolи может ускорить обработку больших данных, но добавляет накладные расходы и может нарушить порядок элементов. - Последний вызванный метод (
parallel()илиsequential()) определяет режим для всего конвейера.