Exercises
Three short Java exercises that exercise records, streams, and Optional.
Three short challenges
EXAMPLE
// 1. Records + pattern matching
sealed interface Shape permits Circle, Square, Rectangle {}
record Circle(double radius) implements Shape {}
record Square(double side) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
static double area(Shape s) {
return switch (s) {
case Circle c -> Math.PI * c.radius() * c.radius();
case Square sq -> sq.side() * sq.side();
case Rectangle r -> r.width() * r.height();
};
}
public static void main(String[] args) {
List<Shape> shapes = List.of(
new Circle(2.0),
new Square(3.0),
new Rectangle(2.0, 4.0)
);
double total = shapes.stream().mapToDouble(MyApp::area).sum();
System.out.printf("total area = %.2f%n", total);
}
// 2. Stream group-by with Collectors
record Order(String customerId, int total) {}
Map<String, Integer> spendByCustomer = orders.stream()
.collect(Collectors.groupingBy(
Order::customerId,
Collectors.summingInt(Order::total)
));
// Top 3 spenders
spendByCustomer.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.limit(3)
.forEach(e -> System.out.println(e.getKey() + ': ' + e.getValue()));
// 3. Optional pipeline - no nulls
Optional<User> userOpt = findUserById(id);
String displayName = userOpt
.map(User::name)
.filter(n -> !n.isBlank())
.orElseGet(() -> userOpt.map(User::email).orElse('anon'));
// Stretch: rewrite #1 using ExtractRecord patterns (Java 21):
// case Circle(double r) -> Math.PI * r * r;
// (Pattern matching for switch with deconstruction.)
Why it matters
Records, sealed types, and pattern matching pull a huge amount of boilerplate out of Java. Combine them with streams and Optional and your data layer code reads like a different language than Java 8.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Discussion
Loading…