Lesson 10 of 13
Lambdas & the Stream API
Learn and the Stream , which let you write many as a short of steps such as filter, map and collect.
import java.util.function.*;
// A lambda is a compact implementation of a single-method interface.
Runnable task = () -> System.out.println("running");
Function<String, Integer> len = s -> s.length();
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
Predicate<String> isEmpty = String::isEmpty; // method reference
Supplier<List<String>> maker = ArrayList::new; // constructor reference
Consumer<String> printer = System.out::println;
// The core functional interfaces you will meet constantly:
// Function<T,R> R apply(T) transform
// Predicate<T> boolean test(T) filter
// Consumer<T> void accept(T) side effect
// Supplier<T> T get() produce
// UnaryOperator<T> Function<T,T>
System.out.println(len.apply("hello")); // 5
System.out.println(add.apply(2, 3)); // 5
// Composition
Function<Integer, Integer> doubled = x -> x * 2;
Function<Integer, Integer> plusTen = x -> x + 10;
System.out.println(doubled.andThen(plusTen).apply(5)); // 20
System.out.println(doubled.compose(plusTen).apply(5)); // 30import java.util.*;
import java.util.stream.*;
record Order(String customer, String region, double total, int items) {}
List<Order> orders = List.of(
new Order("Ada", "EU", 120.50, 3),
new Order("Bob", "US", 45.00, 1),
new Order("Cleo", "EU", 310.75, 8),
new Order("Dan", "US", 210.00, 4),
new Order("Ada", "EU", 60.25, 2)
);
// Filter -> map -> collect
List<String> bigEuCustomers = orders.stream()
.filter(o -> o.region().equals("EU"))
.filter(o -> o.total() > 100)
.map(Order::customer)
.distinct()
.sorted()
.toList(); // [Ada, Cleo]
// Reductions
double revenue = orders.stream().mapToDouble(Order::total).sum();
OptionalDouble avg = orders.stream().mapToDouble(Order::total).average();
Optional<Order> biggest = orders.stream().max(Comparator.comparingDouble(Order::total));
System.out.println(revenue); // 746.5
System.out.println(biggest.map(Order::customer).orElse("none")); // Cleo
// Sorting by several keys
List<Order> sorted = orders.stream()
.sorted(Comparator.comparing(Order::region)
.thenComparing(Comparator.comparingDouble(Order::total).reversed()))
.toList();import java.util.*;
import java.util.stream.*;
// Collectors do the heavy lifting for grouping and summarising.
Map<String, List<Order>> byRegion = orders.stream()
.collect(Collectors.groupingBy(Order::region));
Map<String, Double> revenueByRegion = orders.stream()
.collect(Collectors.groupingBy(Order::region,
Collectors.summingDouble(Order::total)));
// {EU=491.5, US=255.0}
Map<Boolean, List<Order>> split = orders.stream()
.collect(Collectors.partitioningBy(o -> o.total() >= 100));
String names = orders.stream()
.map(Order::customer)
.distinct()
.collect(Collectors.joining(", ", "[", "]")); // [Ada, Bob, Cleo, Dan]
DoubleSummaryStatistics stats = orders.stream()
.collect(Collectors.summarizingDouble(Order::total));
System.out.println(stats.getMax() + " " + stats.getCount());
// flatMap flattens nested structures
List<List<String>> tags = List.of(List.of("a", "b"), List.of("c"));
List<String> flat = tags.stream().flatMap(List::stream).toList(); // [a, b, c]
// Generating streams
List<Integer> firstTen = Stream.iterate(1, n -> n + 1).limit(10).toList();
IntStream.rangeClosed(1, 5).forEach(System.out::println);Finished reading?Mark it done to track your progress.
Tip: use the ← and → keys to move between lessons.