Last 30 Days
No notifications
A Stream is a lazy pipeline of operations on a sequence of elements. You build it from a source (collection, array, generator), chain *intermediate* operations (map, filter, sorted), and finish with a *terminal* operation (collect, reduce, forEach). Streams replace half the for-loops you used to write — and read more like a description of *what* you want, not *how* to compute it.
# Streams API
SOURCE → intermediate ops (lazy) → terminal op (eager)
Nothing happens until the terminal op runs.List<String> names = List.of("alice", "bob", "carol", "dan");List<String> result = names.stream() // SOURCE
.filter(n -> n.length() > 3) // intermediate
.map(String::toUpperCase) // intermediate
.sorted() // intermediate
.toList(); // TERMINAL (Java 16+)
System.out.println(result); // [ALICE, CAROL]
list.stream();
Arrays.stream(arr);
Stream.of("a", "b", "c");
Stream.iterate(1, x -> x * 2).limit(5); // 1, 2, 4, 8, 16
Stream.generate(Math::random).limit(3);
IntStream.range(0, 10); // 0..9
IntStream.rangeClosed(1, 10); // 1..10| op | does |
filter(pred) | keep elements matching pred |
map(fn) | transform each element |
flatMap(fn) | map each → stream, then flatten |
sorted() / sorted(cmp) | sort |
distinct() | drop duplicates |
limit(n) | first n |
skip(n) | drop first n |
peek(c) | side-effect (debug only) |
| op | returns |
toList() | List |
collect(...) | anything via a Collector |
forEach(c) | void |
count() | long |
min(cmp) / max(cmp) | Optional |
findFirst() / findAny() | Optional |
anyMatch / allMatch / noneMatch | boolean |
reduce(...) | aggregate (sum, product, …) |
import static java.util.stream.Collectors.*;people.stream().collect(toList());
people.stream().collect(toSet());
people.stream().collect(toMap(Person::id, p -> p));
people.stream().collect(groupingBy(Person::department));
people.stream().collect(groupingBy(Person::department, counting()));
people.stream().collect(partitioningBy(p -> p.salary() > 50000));
words.stream().collect(joining(", ", "[", "]")); // [a, b, c]
int sum = nums.stream().reduce(0, Integer::sum);
String concat = words.stream().reduce("", String::concat);
Optional<Integer> max = nums.stream().reduce(Integer::max);IntStream, LongStream, DoubleStream add sum, average, min, max, mapToObj.
int total = IntStream.rangeClosed(1, 100).sum(); // 5050
double avg = nums.stream().mapToInt(Integer::intValue).average().orElse(0);long count = bigList.parallelStream().filter(...).count();
Only worth it for CPU-heavy ops on large data; the work is split via the *common ForkJoinPool*.peek is for debugging only — don't mutate state through it.forEach doesn't guarantee order on parallel streams; use forEachOrdered if you need it.