Stream Processing Patterns
Introduction to Stream Processing
Stream processing involves transforming, filtering, and aggregating data using a sequence of operations that can be chained together efficiently.
Core Processing Patterns
Filtering Pattern
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
Mapping Pattern
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream()
.map(String::length)
.collect(Collectors.toList());
Reduction Pattern
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
Advanced Processing Techniques
Grouping and Partitioning
Map<Boolean, List<Integer>> partitionedNumbers = numbers.stream()
.collect(Collectors.partitioningBy(n -> n % 2 == 0));
Map<Integer, List<String>> groupedByLength = names.stream()
.collect(Collectors.groupingBy(String::length));
Stream Processing Workflow
graph LR
A[Source] --> B[Intermediate Operations]
B --> C[Terminal Operation]
C --> D[Result]
Processing Pattern Categories
Category |
Description |
Example Operations |
Filtering |
Select elements |
filter() , distinct() |
Mapping |
Transform elements |
map() , flatMap() |
Reduction |
Aggregate elements |
reduce() , collect() |
Matching |
Check element conditions |
anyMatch() , allMatch() |
Finding |
Locate elements |
findFirst() , findAny() |
Parallel Processing
List<Integer> processedNumbers = numbers.parallelStream()
.map(n -> n * 2)
.filter(n -> n > 10)
.collect(Collectors.toList());
Complex Processing Example
List<String> complexProcessing = names.stream()
.filter(name -> name.length() > 3)
.map(String::toUpperCase)
.sorted()
.collect(Collectors.toList());
- Use appropriate intermediate operations
- Minimize number of stream operations
- Leverage parallel streams for large datasets
- Avoid unnecessary boxing/unboxing
Error Handling Patterns
Optional<Integer> result = numbers.stream()
.filter(n -> n > 0)
.findFirst()
.orElse(null);
Best Practices
- Chain operations efficiently
- Use method references when possible
- Prefer immutable operations
- Close streams after processing
Common Pitfalls
- Reusing streams
- Excessive intermediate operations
- Ignoring lazy evaluation
- Inappropriate stream source selection
Advanced Collectors
String joined = names.stream()
.collect(Collectors.joining(", ", "Prefix-", "-Suffix"));
LabEx recommends practicing these patterns to master stream processing techniques and write more concise, functional Java code.