Master Java Stream API: 20 Real‑World Examples and Best Practices
This tutorial walks through Java 8 Stream fundamentals, covering creation, intermediate operations (filter, map, flatMap, reduce), terminal actions, collectors, grouping, sorting, and parallel streams, illustrated with 20 practical code examples that transform and analyze collections of objects such as employee records.
This article demonstrates how the Java 8 Stream API, together with lambda expressions, provides a declarative way to process collections.
Creating Streams
Streams can be obtained from collections, arrays or static factory methods:
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> s1 = list.stream();
Stream<String> s2 = Stream.of("x", "y", "z");
IntStream intStream = IntStream.of(1, 2, 3);Intermediate Operations
Filtering
Retain only elements that satisfy a predicate:
List<Integer> numbers = Arrays.asList(1, 6, 7, 8, 2);
List<Integer> greaterThanSix = numbers.stream()
.filter(x -> x > 6)
.collect(Collectors.toList()); // [7, 8]Mapping and FlatMapping
Transform each element ( map) or replace an element with another stream and flatten the result ( flatMap).
String[] words = {"abcd", "bcdd", "defde", "fTr"};
List<String> upper = Arrays.stream(words)
.map(String::toUpperCase)
.collect(Collectors.toList()); // [ABCD, BCDD, DEFDE, FTR]
List<String> csv = Arrays.asList("m,k,l,a", "1,3,5,7");
List<String> flat = csv.stream()
.flatMap(s -> Arrays.stream(s.split(",")))
.collect(Collectors.toList()); // [m, k, l, a, 1, 3, 5, 7]Distinct, Limit, Skip
Remove duplicates, limit the number of processed elements, or skip a prefix:
Stream<String> distinct = Stream.concat(Stream.of("a", "b"), Stream.of("b", "c"))
.distinct(); // [a, b, c]
List<Integer> firstTen = Stream.iterate(1, n -> n + 2)
.limit(10)
.collect(Collectors.toList()); // [1,3,5,7,9,11,13,15,17,19]
List<Integer> afterSkip = Stream.iterate(1, n -> n + 2)
.skip(1)
.limit(5)
.collect(Collectors.toList()); // [3,5,7,9,11]Sorting
Natural order or custom comparator:
List<Person> people = ...;
List<String> bySalaryDesc = people.stream()
.sorted(Comparator.comparing(Person::getSalary).reversed())
.map(Person::getName)
.collect(Collectors.toList());Terminal Operations
Collecting
Gather stream elements into containers or aggregate values using Collectors:
// toList / toSet
List<Integer> evens = numbers.stream()
.filter(x -> x % 2 == 0)
.collect(Collectors.toList());
Set<Integer> evenSet = numbers.stream()
.filter(x -> x % 2 == 0)
.collect(Collectors.toSet());
// toMap – map a key to a value
Map<String, Person> highEarners = people.stream()
.filter(p -> p.getSalary() > 8000)
.collect(Collectors.toMap(Person::getName, p -> p));Statistical Summaries
Built‑in collectors for counting, averaging, summing and full statistics:
long count = people.stream().collect(Collectors.counting());
double avgSalary = people.stream().collect(Collectors.averagingDouble(Person::getSalary));
int totalSalary = people.stream().collect(Collectors.summingInt(Person::getSalary));
IntSummaryStatistics stats = people.stream().collect(Collectors.summarizingInt(Person::getSalary));Grouping and Partitioning
Group elements by a key or partition them by a boolean predicate:
// Partition by salary > 8000
Map<Boolean, List<Person>> byHighSalary = people.stream()
.collect(Collectors.partitioningBy(p -> p.getSalary() > 8000));
// Group by gender
Map<String, List<Person>> byGender = people.stream()
.collect(Collectors.groupingBy(Person::getSex));
// Multi‑level grouping: gender then area
Map<String, Map<String, List<Person>>> byGenderArea =
people.stream().collect(Collectors.groupingBy(Person::getSex,
Collectors.groupingBy(Person::getArea)));Joining
Concatenate string representations with a delimiter:
String names = people.stream()
.map(Person::getName)
.collect(Collectors.joining(",")); // e.g. "Tom,Jack,Lily"Reducing
Custom reduction using reduce or Collectors.reducing:
int sum = numbers.stream().reduce(0, Integer::sum);
Optional<Integer> max = numbers.stream().reduce(Integer::max);
// Example with a custom accumulator
Integer netSalarySum = people.stream()
.collect(Collectors.reducing(0, Person::getSalary, (s, sal) -> s + sal - 5000));Parallel Streams
Convert a sequential stream to parallel for potential performance gains on large data sets:
Optional<Integer> firstMatch = numbers.parallelStream()
.filter(x -> x > 6)
.findFirst();Employee Example
A simple Person class is used throughout the examples:
public class Person {
private String name;
private int salary;
private int age;
private String sex;
private String area;
public Person(String name, int salary, int age, String sex, String area) {
this.name = name;
this.salary = salary;
this.age = age;
this.sex = sex;
this.area = area;
}
// getters and setters omitted for brevity
}Typical operations demonstrated with this class include:
Filtering employees with salary > 8000 and collecting the result.
Finding the employee with the highest salary using max or sorted.
Increasing every employee's salary by a fixed amount (both immutable and mutable approaches).
Collecting all employee names into a comma‑separated string.
Grouping by gender, by area, and by the combination of gender + area.
Partitioning by whether salary exceeds a threshold.
Summary
By leveraging the Stream API you can replace verbose loops with concise, readable pipelines that support lazy evaluation, parallel execution, and a rich set of built‑in collectors for aggregation, grouping, and reduction.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
