Stream API
29 вопросов и ответов в разделе Stream API.
Вопросы этого раздела
- Какие преимущества даёт использование Stream API?
- В чём разница между intermediate и terminal операциями?
- Что делает операция filter()?
- Что делает операция map()?
- Что делает операция collect()?
- Что такое Collector и какие есть встроенные Collectors?
- Что делает операция flatMap()?
- В чём разница между map() и flatMap()?
- Что такое параллельные стримы?
- Когда использовать parallel streams?
- Как создать parallel stream?
- Какие потенциальные проблемы могут быть с параллельными стримами?
- Что такое ForkJoinPool и как он связан с parallel streams?
- Можно ли изменять состояние внешних переменных в Stream операциях?
- Что такое побочные эффекты (side effects) в Stream?
- Почему следует избегать побочных эффектов в Stream?
- Что делает операция reduce()?
- В чём разница между reduce() и collect()?
- Что такое операция peek() и когда её использовать?
- Можно ли повторно использовать Stream?
- Что такое lazy evaluation в Stream?
- Когда начинается выполнение операций в Stream?
- Что делают операции distinct(), sorted(), limit(), skip()?
- Как работает короткое замыкание (short-circuiting) в Stream?
- Что такое операции anyMatch(), allMatch(), noneMatch()?
- Что делают операции findFirst() и findAny()?
- Как собрать Stream в Map?
- Что делать при коллизиях ключей при сборке в Map?
- Как работать с Optional в Stream?
Навигатор по разделу
29 вопросов для подготовки к собеседованию на Middle Java Developer.
📋 Все вопросы
🗺️ Карта зависимостей тем
┌──────────────────────────────────────────┐
│ STREAM BASICS (1-2) │
│ 1. Преимущества Stream API │
│ 2. Intermediate vs Terminal │
└──────────────────┬───────────────────────┘
│
┌──────────────────────────┼──────────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌────────────────────┐
│ CORE OPS │ │ COLLECT & │ │ PARALLEL │
│ (3-8) │ │ REDUCE (5-8) │ │ (9-13) │
│ 3. filter() │ │ 5. collect() │ │ 9. Parallel streams│
│ 4. map() │ │ 6. Collector │ │ 10. When to use │
│ 7. flatMap() │ │ 7. flatMap() │ │ 11. Как создать │
│ 8. map vs fmap │ │ 8. map vs fmap│ │ 12. Проблемы │
│ │ │ 17. reduce() │ │ 13. ForkJoinPool │
│ │ │ 18. reduce vs │ │ │
│ │ │ collect │ │ │
└───────┬───────┘ └───────┬───────┘ └────────┬───────────┘
│ │ │
└────────────────────────┼────────────────────────┘
▼
┌──────────────────────────────────────────┐
│ CONCEPTS & PITFALLS (14-22) │
│ 14. Внешние переменные │
│ 15-16. Побочные эффекты │
│ 19. peek() │
│ 20. Повторное использование │
│ 21-22. Lazy evaluation │
└──────────────────────────────────────────┘
│
┌────────────────────────┼────────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌────────────────────┐
│ ADVANCED OPS │ │ MAP & OPT │ │ │
│ (23-26) │ │ (27-29) │ │ │
│ 23. distinct, │ │ 27. toMap │ │ │
│ sorted, │ │ 28. Collisions │ │ │
│ limit, skip│ │ 29. Optional │ │ │
│ 24. Short-cir│ │ │ │ │
│ 25. match() │ │ │ │ │
│ 26. findFirst │ │ │ │ │
└───────────────┘ └───────────────┘ └────────────────────┘
🎯 Рекомендуемый порядок изучения
🟢 Уровень Junior (недели 1-2)
| Шаг | Тема | Файлы | Цель |
|---|---|---|---|
| 1 | Stream基本概念 | Q1, Q2 | Что такое Stream, lazy, intermediate vs terminal |
| 2 | Основные операции | Q3, Q4 | filter(), map() |
| 3 | collect() | Q5 | toList(), toSet(), joining() |
| 4 | map vs flatMap | Q7, Q8 | Когда map, когда flatMap |
| 5 | peek, reuse | Q19, Q20 | peek для отладки, нельзя переиспользовать |
| 6 | Lazy evaluation | Q21, Q22 | Когда начинается выполнение |
🟡 Уровень Middle (недели 3-4)
| Шаг | Тема | Файлы | Цель |
|---|---|---|---|
| 1 | Collector deep dive | Q6 | characteristics, custom Collector, teeing |
| 2 | reduce vs collect | Q17, Q18 | Immutable vs mutable reduction |
| 3 | Parallel streams | Q9, Q10, Q11 | Когда parallel, когда sequential |
| 4 | Problems with parallel | Q12, Q13 | Cache locality, ForkJoinPool, work-stealing |
| 5 | Side effects | Q14, Q15, Q16 | Почему избегать, stateful ops |
| 6 | Advanced ops | Q23, Q24, Q25 | stateful ops, short-circuit, match |
| 7 | findFirst/findAny | Q26 | Ordered vs unordered, parallel impact |
🔴 Уровень Senior (недели 5-6)
| Шаг | Тема | Файлы | Цель |
|---|---|---|---|
| 1 | ForkJoinPool internals | Q13 (Senior) | Deque, LIFO/FIFO, work-stealing algorithm |
| 2 | Collector internals | Q6 (Senior) | Supplier/Accumulator/Combiner/Finisher, characteristics |
| 3 | Parallel pitfalls | Q12 (Senior) | Cache thrashing, ThreadLocal, boxed primitives |
| 4 | Short-circuit optimization | Q24 (Senior) | Java 9+ count() optimization, SIZED sources |
| 5 | Map collection pitfalls | Q27, Q28 | toMap vs groupingBy, merge function, parallel combiner |
| 6 | Optional in Stream | Q29 | orElse vs orElseGet, flatMap with Optional |
| 7 | Performance tuning | Q9-Q13 (Senior) | N×Q > 10,000 rule, unordered optimization, custom FJP |
🔗 Ключевые связи между темами
Тема: Основные операции
Q1 (Stream API) → Q2 (Intermediate vs Terminal) → Q3 (filter) → Q4 (map)
↓ ↓
Q7 (flatMap) ←────────────────────────────── Q8 (map vs flatMap)
Ключевые связи:
- Q2 ↔ Q21: Intermediate операции ленивы, выполняются только при terminal
- Q3 ↔ Q24: filter — short-circuit операция, может остановить пайплайн рано
- Q4 ↔ Q7: map = 1→1, flatMap = 1→N + flatten
- Q8 ↔ Q17: map преобразует, reduce/aggregates — сворачивает
Тема: Collect и Reduce
Q5 (collect) → Q6 (Collector) → Q17 (reduce) → Q18 (reduce vs collect)
↓ ↓
Q27 (toMap) → Q28 (Коллизии ключей)
Ключевые связи:
- Q5 ↔ Q6: collect принимает Collector — «рецепт» сбора
- Q6 ↔ Q18: Collector = mutable reduction, reduce = immutable reduction
- Q17 ↔ Q18: reduce для простых значений, collect для коллекций
- Q27 ↔ Q28: toMap бросает при дубликатах → merge function
Тема: Параллелизм
Q9 (Parallel streams) → Q10 (Когда использовать) → Q11 (Как создать)
↓ ↓
Q12 (Проблемы) ←──── Q13 (ForkJoinPool)
Ключевые связи:
- Q9 ↔ Q13: parallelStream = ForkJoinPool.commonPool()
- Q10 ↔ Q12: Когда parallel помогает vs когда вредит
- Q12 ↔ Q14: Side effects в parallel → race conditions
- Q13 ↔ Q24: work-stealing алгоритм, LIFO/FIFO deque
Тема: Продвинутые операции
Q23 (distinct/sorted/limit/skip) → Q24 (Short-circuit)
↓ ↓
Q25 (anyMatch/allMatch/noneMatch) → Q26 (findFirst/findAny)
↓
Q29 (Optional)
Ключевые связи:
- Q23 ↔ Q24: limit/skip/findFirst — short-circuit операции
- Q24 ↔ Q25: match-операции = short-circuit terminal
- Q25 ↔ Q26: anyMatch ≈ findAny().isPresent(), но без Optional overhead
- Q26 ↔ Q29: findFirst/findAny возвращают Optional
🎓 Шпаргалка: что знать для каждого уровня
🟢 Junior
- Stream ≠ Collection: Stream не хранит данные, это конвейер операций
- Intermediate (filter, map, flatMap) — ленивые, terminal (collect, forEach, count) — запускают
- filter = отсев, map = преобразование 1→1, flatMap = 1→N + flatten
- collect = собрать результат в List/Map/Set
- Stream нельзя переиспользовать — после terminal операции он исчерпан
🟡 Middle
- Lazy evaluation: операции выполняются element-by-element, не stage-by-stage
- Stateful операции (distinct, sorted) требуют знания всех элементов — убивают параллелизм
- Short-circuit (findFirst, anyMatch, limit) — могут остановить пайплайн рано
- parallelStream = ForkJoinPool.commonPool(), cores-1 воркеров
- Side effects в Stream → баги в parallelStream, используйте collect вместо
- reduce (immutable) vs collect (mutable) — collect эффективнее для коллекций
🔴 Senior
- ForkJoinPool: per-thread Deque, LIFO для владельца, FIFO для воров
- Spliterator характеристики: SIZED критичен для parallel (точный split)
- N × Q > 10,000 правило: когда parallel окупается
- Java 9+: count() оптимизирован для SIZED источников — peek не выполнится
- orElse (eager) vs orElseGet (lazy) — orElseGet для дорогих дефолтов
- Cache thrashing в parallel: потоки пишут в одну cache line → degradation
- Custom ForkJoinPool для isolation, но не для I/O (используйте Virtual Threads)
📝 Формат каждого файла
Каждый файл содержит:
- 🟢 Junior Level — базовое понимание, простые аналогии, примеры
- 🟡 Middle Level — внутренности, типичные ошибки, практические примеры
- 🔴 Senior Level — deep dive, edge cases, production experience, monitoring
- 🎯 Шпаргалка для интервью — ключевые тезисы, частые вопросы, красные флаги, связанные темы