โ What are Streams?
A Stream is a sequence of elements supporting sequential and parallel aggregate operations. It doesn't store data but conveys elements from a source like a collection, array, or I/O channel.
๐ Key Characteristics:
- Lazy Evaluation: Intermediate operations are lazy and executed only when a terminal operation is invoked.
- Immutable: Doesn’t modify the original data source.
- Can be parallelized easily
๐ง Stream Pipeline Structure:
Stream<T> stream = collection.stream()
.filter(...)
.map(...)
.sorted(...)
.collect(...);
๐งช Common Stream Methods:
|
Type |
Method |
Description |
|
Intermediate |
filter() |
Filters elements by predicate |
|
map() |
Transforms elements |
|
|
flatMap() |
Flattens nested structures |
|
|
sorted() |
Sorts elements |
|
|
distinct() |
Removes duplicates |
|
|
Terminal |
collect() |
Converts stream to collection |
|
forEach() |
Iterates over elements |
|
|
reduce() |
Aggregates elements |
|
|
count(), min(), max() |
Self-explanatory |
๐ Examples:
โ Filter & Map:
List<String> names = people.stream()
.filter(p -> p.getAge() > 18)
.map(Person::getName)
.collect(Collectors.toList());
โ Group By:
Map<String, List<Person>> byCity = people.stream()
.collect(Collectors.groupingBy(Person::getCity));
โ Count Frequency:
Map<String, Long> freq = items.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
โ Reduce Example:
int sum = numbers.stream().reduce(0, Integer::sum);
โ Parallel Stream:
list.parallelStream().forEach(System.out::println);
๐ฅ Tip: Use parallel streams carefully for CPU-bound operations on large datasets.
โ ๏ธ Common Pitfalls:
- Streams cannot be reused once consumed.
- Be cautious mixing forEach and collect.
- Avoid stateful lambdas in parallel streams.