You are viewing a free preview of this lesson.
Subscribe to unlock all 10 lessons in this course and every other course on LearningBro.
Java has evolved rapidly since adopting a six-month release cadence in 2017. This lesson covers the most impactful features from Java 8 through Java 21, including lambdas, streams, records, sealed classes, pattern matching, and virtual threads.
A lambda is a concise way to represent a function (an implementation of a functional interface):
// Before lambdas
Comparator<String> cmp = new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.length() - b.length();
}
};
// With a lambda
Comparator<String> cmp = (a, b) -> a.length() - b.length();
// No parameters
Runnable r = () -> System.out.println("Running");
// One parameter (parentheses optional)
Consumer<String> greet = name -> System.out.println("Hello, " + name);
// Multiple parameters
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
// Multi-line body
Comparator<String> cmp = (a, b) -> {
int diff = a.length() - b.length();
return diff != 0 ? diff : a.compareTo(b);
};
| Interface | Method | Signature |
|---|---|---|
Predicate<T> | test | T → boolean |
Function<T, R> | apply | T → R |
Consumer<T> | accept | T → void |
Supplier<T> | get | () → T |
BiFunction<T, U, R> | apply | (T, U) → R |
Comparator<T> | compare | (T, T) → int |
A shorthand for lambdas that call an existing method:
// Lambda
names.forEach(name -> System.out.println(name));
// Method reference
names.forEach(System.out::println);
| Type | Syntax | Example |
|---|---|---|
| Static method | Class::method | Integer::parseInt |
| Instance method (specific) | object::method | System.out::println |
| Instance method (arbitrary) | Class::method | String::toUpperCase |
| Constructor | Class::new | ArrayList::new |
Streams provide a functional pipeline for processing collections:
List<String> names = List.of("Alice", "Bob", "Charlie", "David", "Eve");
List<String> result = names.stream()
.filter(name -> name.length() > 3) // keep names longer than 3
.map(String::toUpperCase) // convert to uppercase
.sorted() // sort alphabetically
.toList(); // collect to a list
// result: [ALICE, CHARLIE, DAVID]
| Operation | Type | Description |
|---|---|---|
filter(predicate) | Intermediate | Keep elements matching the predicate |
map(function) | Intermediate | Transform each element |
flatMap(function) | Intermediate | Flatten nested structures |
sorted() | Intermediate | Sort elements |
distinct() | Intermediate | Remove duplicates |
limit(n) | Intermediate | Take first n elements |
forEach(consumer) | Terminal | Perform an action on each element |
collect(collector) | Terminal | Gather results (e.g., to a list) |
count() | Terminal | Count elements |
reduce(identity, op) | Terminal | Combine elements into a single value |
anyMatch(predicate) | Terminal | True if any element matches |
allMatch(predicate) | Terminal | True if all elements match |
int total = List.of(1, 2, 3, 4, 5).stream()
.reduce(0, Integer::sum); // 15
Optional Class (Java 8)Optional represents a value that may or may not be present — a safer alternative to null:
Optional<String> maybeName = Optional.ofNullable(getName());
String name = maybeName.orElse("Unknown");
maybeName.ifPresent(n -> System.out.println("Found: " + n));
Subscribe to continue reading
Get full access to this lesson and all 10 lessons in this course.