Mastering Java 8 Stream API: 20 Real‑World Examples
This tutorial walks through Java 8 Stream and Lambda features, explaining stream concepts, intermediate and terminal operations, and demonstrating twenty practical examples—including creation, filtering, mapping, reduction, collection, sorting, and combining—using an employee class to illustrate each operation.
What Is a Stream?
In Java 8, a Stream treats a collection of elements as a flow, allowing operations such as filtering, sorting, and aggregation via the Stream API.
Stream operations are divided into two categories:
Intermediate operations that return a new stream and can be chained.
Terminal operations that produce a final result (a collection, a value, or a side effect) and close the stream.
Key characteristics of streams:
Streams do not store data; they compute results on demand.
Streams do not modify the source; they produce new collections or values.
Streams are lazy; intermediate operations execute only when a terminal operation is invoked.
Creating Streams
Streams can be created from collections, arrays, or static factory methods:
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream(); // sequential
Stream<String> parallel = list.parallelStream(); // parallel int[] array = {1,3,5,6,8};
IntStream stream = Arrays.stream(array); Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
Stream<Integer> iter = Stream.iterate(0, x -> x + 3).limit(4);
Stream<Double> gen = Stream.generate(Math::random).limit(3);0 3 6 9 0.6796156909271994 0.1914314208854283 0.8116932592396652
Sequential streams process elements in order on the main thread, while parallel streams split the work across multiple threads when ordering is not required.
Optional<Integer> findFirst = list.stream().parallel().filter(x -> x > 6).findFirst();Employee Class Used in the Examples
class Person {
private String name; // name
private int salary; // salary
private int age; // age
private String sex; // gender
private String area; // region
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
}3.1 Traversal / Matching (forEach / find / anyMatch)
List<Integer> list = Arrays.asList(7,6,9,3,8,2,1);
list.stream().filter(x -> x > 6).forEach(System.out::println);
Optional<Integer> first = list.stream().filter(x -> x > 6).findFirst();
Optional<Integer> any = list.parallelStream().filter(x -> x > 6).findAny();
boolean anyMatch = list.stream().anyMatch(x -> x < 6);
System.out.println("First: " + first.get());
System.out.println("Any: " + any.get());
System.out.println("Contains <6: " + anyMatch);3.2 Filtering (filter)
List<Integer> list = Arrays.asList(6,7,3,8,1,2,9);
list.stream().filter(x -> x > 7).forEach(System.out::println);8 9
List<Person> personList = new ArrayList<>();
// add Person objects …
List<String> highEarners = personList.stream()
.filter(p -> p.getSalary() > 8000)
.map(Person::getName)
.collect(Collectors.toList());
System.out.println("Names >8000: " + highEarners);Names >8000: [Tom, Anni, Owen]
3.3 Aggregation (max / min / count)
List<String> list = Arrays.asList("adnm","admmt","pot","xbangd","weoujgsd");
Optional<String> max = list.stream().max(Comparator.comparing(String::length));
System.out.println("Longest: " + max.get());Longest: weoujgsd
List<Integer> list = Arrays.asList(7,6,9,4,11,6);
Optional<Integer> max = list.stream().max(Integer::compareTo);
System.out.println("Max: " + max.get());Max: 11
Optional<Person> maxSalary = personList.stream()
.max(Comparator.comparingInt(Person::getSalary));
System.out.println("Highest salary: " + maxSalary.get().getSalary());Highest salary: 9500
List<Integer> list = Arrays.asList(7,6,4,8,2,11,9);
long count = list.stream().filter(x -> x > 6).count();
System.out.println("Count >6: " + count);Count >6: 4
3.4 Mapping (map / flatMap)
String[] arr = {"abcd","bcdd","defde","fTr"};
List<String> upper = Arrays.stream(arr)
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(upper);[ABCD, BCDD, DEFDE, FTR]
List<Integer> intList = Arrays.asList(1,3,5,7,9,11);
List<Integer> plus3 = intList.stream()
.map(x -> x + 3)
.collect(Collectors.toList());
System.out.println(plus3);[4, 6, 8, 10, 12, 14]
List<Person> personList = …;
List<Person> increased = personList.stream()
.map(p -> {
Person copy = new Person(p.getName(), 0, 0, null, null);
copy.setSalary(p.getSalary() + 10000);
return copy;
})
.collect(Collectors.toList());
System.out.println("Before: " + personList.get(0).getSalary());
System.out.println("After: " + increased.get(0).getSalary());Before: 8900 After: 18900
List<String> list = Arrays.asList("m,k,l,a", "1,3,5,7");
List<String> flat = list.stream()
.flatMap(s -> Arrays.stream(s.split(",")))
.collect(Collectors.toList());
System.out.println(flat);[m, k, l, a, 1, 3, 5, 7]
3.5 Reduction (reduce)
List<Integer> list = Arrays.asList(1,3,2,8,11,4);
Optional<Integer> sum = list.stream().reduce((a,b) -> a + b);
Optional<Integer> product = list.stream().reduce((a,b) -> a * b);
Optional<Integer> max = list.stream().reduce((a,b) -> a > b ? a : b);
System.out.println("Sum: " + sum.get());
System.out.println("Product: " + product.get());
System.out.println("Max: " + max.get());Sum: 29 Product: 2112 Max: 11
Integer taxSum = personList.stream()
.collect(Collectors.reducing(0, Person::getSalary, (a,b) -> a + b - 5000));
System.out.println("Taxed sum: " + taxSum);Taxed sum: 8700
3.6 Collecting (collect)
List<Integer> list = Arrays.asList(1,6,3,4,6,7,9,6,20);
List<Integer> evens = list.stream()
.filter(x -> x % 2 == 0)
.collect(Collectors.toList());
Set<Integer> evenSet = list.stream()
.filter(x -> x % 2 == 0)
.collect(Collectors.toSet());
Map<String, Person> map = personList.stream()
.filter(p -> p.getSalary() > 8000)
.collect(Collectors.toMap(Person::getName, p -> p));
System.out.println(evens);
System.out.println(evenSet);
System.out.println(map);toList: [6, 4, 6, 6, 20] toSet: [4, 20, 6] toMap: {Tom=..., Anni=...}
Long count = personList.stream().collect(Collectors.counting());
Double avg = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary));
DoubleSummaryStatistics stats = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
System.out.println("Count: " + count);
System.out.println("Avg: " + avg);
System.out.println("Sum: " + sum);
System.out.println("Stats: " + stats);Count: 3 Avg: 7900.0 Sum: 23700 Stats: DoubleSummaryStatistics{count=3, sum=23700.0, min=7000.0, average=7900.0, max=8900.0}
Map<Boolean, List<Person>> partition = personList.stream()
.collect(Collectors.partitioningBy(p -> p.getSalary() > 8000));
Map<String, List<Person>> bySex = personList.stream()
.collect(Collectors.groupingBy(Person::getSex));
Map<String, Map<String, List<Person>>> bySexArea = personList.stream()
.collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
System.out.println(partition);
System.out.println(bySex);
System.out.println(bySexArea);partition: {false=[...], true=[...]} bySex: {female=[...], male=[...]} bySexArea: {female={New York=[...], Washington=[...]}, male={New York=[...], Washington=[...]}}
String names = personList.stream()
.map(Person::getName)
.collect(Collectors.joining(","));
System.out.println("Names: " + names);Names: Tom,Jack,Lily
3.7 Sorting (sorted)
List<String> bySalary = personList.stream()
.sorted(Comparator.comparing(Person::getSalary))
.map(Person::getName)
.collect(Collectors.toList());
List<String> bySalaryDesc = personList.stream()
.sorted(Comparator.comparing(Person::getSalary).reversed())
.map(Person::getName)
.collect(Collectors.toList());
List<String> bySalaryThenAge = personList.stream()
.sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge))
.map(Person::getName)
.collect(Collectors.toList());
List<String> custom = personList.stream()
.sorted((p1,p2) -> {
if (p1.getSalary() == p2.getSalary()) {
return p2.getAge() - p1.getAge();
} else {
return p2.getSalary() - p1.getSalary();
}
})
.map(Person::getName)
.collect(Collectors.toList());
System.out.println(bySalary);
System.out.println(bySalaryDesc);
System.out.println(bySalaryThenAge);
System.out.println(custom);bySalary: [Lily, Tom, Sherry, Jack, Alisa] bySalaryDesc: [Sherry, Jack, Alisa, Tom, Lily] bySalaryThenAge: [Lily, Tom, Sherry, Jack, Alisa] custom: [Alisa, Jack, Sherry, Tom, Lily]
3.8 Extraction / Combination
String[] arr1 = {"a","b","c","d"};
String[] arr2 = {"d","e","f","g"};
List<String> merged = Stream.concat(Stream.of(arr1), Stream.of(arr2))
.distinct()
.collect(Collectors.toList());
List<Integer> limited = Stream.iterate(1, x -> x + 2)
.limit(10)
.collect(Collectors.toList());
List<Integer> skipped = Stream.iterate(1, x -> x + 2)
.skip(1)
.limit(5)
.collect(Collectors.toList());
System.out.println("Merged: " + merged);
System.out.println("Limited: " + limited);
System.out.println("Skipped: " + skipped);Merged: [a, b, c, d, e, f, g] Limited: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] Skipped: [3, 5, 7, 9, 11]
These examples cover the essential operations of Java 8 streams, providing a solid foundation for functional-style processing of collections.
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.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
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.
