Java 8 Features
Java 8, released in March 2014, is one of the most important releases in the history of Java. It added functional programming features to the language: you can now pass behavior, such as "keep only even numbers", as a value, and process collections in a short, readable pipeline. Most modern Java code is written in this style. In this lesson, you will get an overview of every major Java 8 feature, with a small example of each. The lessons that follow cover each one in detail.
Main Features of Java 8
| Feature | What it gives you |
|---|---|
| Lambda expressions | It is used to write a short, unnamed function: x -> x * 2. |
| Functional interfaces | Interfaces with one abstract method, which lambdas implement. |
| Method references | A shorter form of a lambda that just calls a method: String::length. |
| Stream API | Process collections with filter, map, sorted, collect and more. |
| Optional | A container that may or may not hold a value, to avoid null checks. |
| Default and static methods in interfaces | Interfaces can have method bodies (see "Default, Static and Private Methods in Interfaces"). |
| forEach method | Loop over any Iterable or Map with a lambda. |
| Date and Time API | LocalDate, LocalDateTime, Duration and more in java.time. |
| Base64 | Built-in encoding and decoding with java.util.Base64. |
| Collection improvements | removeIf, replaceAll, Map.merge, computeIfAbsent, getOrDefault. |
Example: Before and After Java 8
Let's see an example that prints the names longer than six letters, in upper case and sorted, first in the old style and then with Java 8 features.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BeforeAfter {
public static void main(String[] args) {
List<String> names =
List.of("Srihitha", "Navika", "Advitha", "Anamaneni");
List<String> oldWay = new ArrayList<>();
for (String n : names) {
if (n.length() > 6) {
oldWay.add(n.toUpperCase());
}
}
Collections.sort(oldWay);
System.out.println("Before Java 8: " + oldWay);
List<String> newWay = names.stream()
.filter(n -> n.length() > 6)
.map(String::toUpperCase)
.sorted()
.toList();
System.out.println("With streams: " + newWay);
}
}Before Java 8: [ADVITHA, ANAMANENI, SRIHITHA]
With streams: [ADVITHA, ANAMANENI, SRIHITHA]Explanation: Both versions give the same result. The old style needs a new list, a loop, an if and a separate sort. The stream version reads like a description of the task: filter the long names, convert them to upper case, sort them, and collect them into a list. (toList() itself was added later, in Java 16.)
Example: A Quick Tour
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
public class Tour {
public static void main(String[] args) {
Predicate<Integer> isEven = n -> n % 2 == 0;
System.out.println("Lambda: is 10 even? " + isEven.test(10));
List<String> names = List.of("Navika", "Srihitha", "Advitha");
names.forEach(System.out::println);
int total = List.of(91, 78, 85).stream()
.mapToInt(Integer::intValue)
.sum();
System.out.println("Stream sum: " + total);
Optional<String> first = names.stream()
.filter(n -> n.startsWith("Z"))
.findFirst();
System.out.println("Optional: " + first.orElse("no match"));
}
}Lambda: is 10 even? true
Navika
Srihitha
Advitha
Stream sum: 254
Optional: no matchExplanation: isEven stores a lambda in a Predicate, a built-in functional interface. forEach(System.out::println) uses a method reference. The stream adds up the marks, and findFirst returns an Optional that is empty because no name starts with Z, so orElse supplies a default.
Common Mistakes
Thinking streams replace every loop. A simple loop is often clearer for small tasks with side effects.
Forgetting that streams don't change the source list. They produce a new result.
Mixing up Java 8 and later features. var (Java 10), toList() (Java 16) and records (Java 16) came after Java 8.
Interview Corner
What are the main features of Java 8?
Lambda expressions, functional interfaces (with the java.util.function package), method references, the Stream API, Optional, default and static methods in interfaces, the forEach method on Iterable and Map, the new java.time Date and Time API, Base64 encoding, new collection methods such as removeIf and Map.merge, and CompletableFuture for asynchronous programming.
Practice
- Easy: Rewrite a loop that prints every even number in a list using
forEachand a lambda with anif. - Harder: Given a list of words, use a stream to produce a sorted list of the distinct first letters in upper case.
Key Takeaways
Was this tutorial helpful?