java 8
java 8
1 Introduction
This guide offers a hands-on exploration of Java 8’s core features, designed for learners
with basic Java knowledge (OOP, collections). It covers Lambda Expressions, Stream
API, Optional, Default/Static Methods, Date/Time API, CompletableFuture, and a practi-
cal project, with examples and best practices to deepen your understanding of modern
Java development.
2 Lambda Expressions
2.1 What Are Lambda Expressions?
2.3 Examples
1. Sorting a List:
1 import java.util.*;
2 List<String> names = Arrays.asList(”Bob”, ”Alice”, ”Charlie”);
3 Collections.sort(names, (a, b) -> a.length() - b.length());
4 System.out.println(names); // [Bob, Alice, Charlie]
1
3. Using Predicate:
1 import java.util.function.Predicate;
2 Predicate<Integer> isEven = n -> n % 2 == 0;
3 System.out.println(isEven.test(4)); // true
2.5 Practice
2.6 Resources
• https://www.baeldung.com/java-8-lambda-expressions-tips
• https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
3.3 Examples
2
1 import java.util.*;
2 import java.util.stream.*;
3 List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
4 List<Integer> even = numbers.stream()
5 .filter(n -> n % 2 == 0)
6 .collect(Collectors.toList());
7 System.out.println(even); // [2, 4]
2. Map to Transform:
1 List<String> names = Arrays.asList(”alice”, ”bob”);
2 List<String> upper = names.stream()
3 .map(String::toUpperCase)
4 .collect(Collectors.toList());
5 System.out.println(upper); // [ALICE, BOB]
3.5 Practice
3.6 Resources
• https://www.baeldung.com/java-8-streams
• http://tutorials.jenkov.com/java-functional-programming/streams.html
These handle complex data processing like grouping, flattening, and parallel process-
ing.
3
4.2 Key Concepts
4.3 Examples
1. FlatMap:
1 import java.util.*;
2 import java.util.stream.*;
3 List<List<String>> nested = Arrays.asList(Arrays.asList(”a”, ”b”),
Arrays.asList(”c”));
4 List<String> flat = nested.stream()
5 .flatMap(List::stream)
6 .collect(Collectors.toList());
7 System.out.println(flat); // [a, b, c]
2. Grouping:
1 import java.util.*;
2 import java.util.stream.*;
3 class Person {
4 String name; int age;
5 Person(String name, int age) { this.name = name; this.age = age; }
6 public String getName() { return name; }
7 public int getAge() { return age; }
8 }
9 List<Person> people = Arrays.asList(new Person(”Alice”, 25), new
Person(”Bob”, 25), new Person(”Charlie”, 30));
10 Map<Integer, List<String>> byAge = people.stream()
11 .collect(Collectors.groupingBy(
12 Person::getAge,
13 Collectors.mapping(Person::getName,
Collectors.toList())
14 ));
15 System.out.println(byAge); // {25=[Alice, Bob], 30=[Charlie]}
3. Reduce:
1 List<Integer> numbers = Arrays.asList(1, 2, 3);
2 int sum = numbers.stream()
3 .reduce(0, (a, b) -> a + b);
4 System.out.println(sum); // 6
4
4.5 Practice
4.6 Resources
• https://www.baeldung.com/java-8-streams
• https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html
5 Optional Class
5.1 What Is Optional?
5.3 Examples
1. Basic Optional:
1 import java.util.Optional;
2 Optional<String> name = Optional.of(”Alice”);
3 System.out.println(name.orElse(”Unknown”)); // Alice
2. Handle Null:
1 String value = null;
2 Optional<String> opt = Optional.ofNullable(value);
3 System.out.println(opt.orElseGet(() -> ”Default”)); // Default
3. Chaining:
1 Optional<String> result = Optional.of(”alice”)
2 .map(String::toUpperCase)
3 .filter(s -> s.length() > 3);
4 System.out.println(result.get()); // ALICE
5
5.4 Best Practices
5.5 Practice
5.6 Resources
• https://www.baeldung.com/java-optional
• https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
6.2 Examples
1. Default Method:
1 interface Vehicle {
2 default void start() {
3 System.out.println(”Vehicle started”);
4 }
5 }
6 class Car implements Vehicle {}
7 Car car = new Car();
8 car.start(); // Vehicle started
2. Static Method:
1 interface MathUtil {
2 static int multiply(int a, int b) {
3 return a * b;
4 }
5 }
6 System.out.println(MathUtil.multiply(5, 3)); // 15
6
6.3 Best Practices
6.4 Practice
6.5 Resources
• https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
• https://www.baeldung.com/java-static-default-methods
The java.time package (JSR-310) provides immutable classes for date and time han-
dling.
7.3 Examples
1. LocalDate:
1 import java.time.LocalDate;
2 LocalDate today = LocalDate.now();
3 LocalDate nextMonth = today.plusMonths(1);
4 System.out.println(nextMonth); // e.g., 2025-07-17
7
3. Time Zones:
1 import java.time.ZonedDateTime;
2 import java.time.ZoneId;
3 ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of(”America/New_York”));
4 System.out.println(zdt); // e.g.,
2025-06-16T11:36-04:00[America/New_York]
7.5 Practice
7.6 Resources
• https://www.baeldung.com/java-8-date-time-intro
• https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html
8 CompletableFuture
8.1 What Is CompletableFuture?
8.3 Examples
1. Async Task:
8
1 import java.util.concurrent.CompletableFuture;
2 CompletableFuture.supplyAsync(() -> ”Hello”)
3 .thenApply(s -> s + ” World”)
4 .thenAccept(System.out::println); // Hello World
2. Error Handling:
1 CompletableFuture.supplyAsync(() -> {
2 throw new RuntimeException(”Error”);
3 }).exceptionally(e -> ”Recovered from ” + e.getMessage())
4 .thenAccept(System.out::println); // Recovered from
java.lang.RuntimeException: Error
8.5 Practice
8.6 Resources
• https://www.baeldung.com/java-completablefuture
• https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/
CompletableFuture.html
9
9.2 Code
1 import java.time.LocalDate;
2 import java.time.format.DateTimeFormatter;
3 import java.util.*;
4 import java.util.concurrent.CompletableFuture;
5 import java.util.stream.*;
6
7 class Employee {
8 String name; int age; double salary; String department; LocalDate hireDate;
9 Employee(String name, int age, double salary, String department, LocalDate
hireDate) {
10 this.name = name; this.age = age; this.salary = salary;
11 this.department = department; this.hireDate = hireDate;
12 }
13 public String getName() { return name; }
14 public int getAge() { return age; }
15 public double getSalary() { return salary; }
16 public String getDepartment() { return department; }
17 public LocalDate getHireDate() { return hireDate; }
18 }
19
20 public class EmployeeSystem {
21 public static void main(String[] args) {
22 List<Employee> employees = Arrays.asList(
23 new Employee(”Alice”, 30, 65000, ”HR”, LocalDate.of(2020, 1, 15)),
24 new Employee(”Bob”, 40, 70000, ”IT”, LocalDate.of(2019, 5, 20)),
25 new Employee(”Charlie”, 28, 55000, ”HR”, LocalDate.of(2021, 3, 10)),
26 new Employee(”David”, 32, 80000, ”IT”, LocalDate.of(2018, 7, 25))
27 );
28 Map<String, List<String>> result = employees.stream()
29 .filter(e -> e.age >= 25 && e.age <= 35)
30 .filter(e -> e.salary > 60000)
31 .collect(Collectors.groupingBy(
32 Employee::getDepartment,
33 Collectors.mapping(e -> e.name + ” (Hired: ” +
34 e.hireDate.format(DateTimeFormatter.ofPattern(”dd-MM-yyyy”)) +
”)”,
35 Collectors.toList())
36 ));
37 System.out.println(result);
38 CompletableFuture.supplyAsync(() -> employees.stream()
39 .mapToDouble(Employee::getSalary)
40 .average()
41 .orElse(0))
42 .thenAccept(avg -> System.out.println(”Average Salary: ” + avg));
43 }
44 }
9.3 Practice
10
• Practice: Explore LeetCode or HackerRank for exercises.
• Community: Engage on Stack Overflow for questions.
11