Java 8 Optional Class Tutorial
1 What Is Optional?
The Optional class in Java 8 holds a value that might not exist. It makes code cleaner by avoiding errors when a value
is missing.
Why Use It?
• Stops errors from missing values.
• Shortens code and makes it clear.
• Fits with Java 8 features like lambdas.
2 Main Methods
2.1 Creating Optional
• Optional.of(value): Holds a value that exists.
• Optional.ofNullable(value): Holds a value or nothing if missing.
• Optional.empty(): Empty Optional.
2.2 Getting Values
• orElse(defaultValue): Returns value or default.
• orElseGet(() -> default): Returns value or computes default.
• orElseThrow(() -> new Exception()): Returns value or throws error.
2.3 Changing Values
• map(function): Changes value if it exists.
• filter(condition): Keeps value if it matches condition.
3 Code Examples: With and Without Optional
3.1 Example 1: Getting a Person’s Name
Without Optional:
1 class Person {
2 String name;
3 Person(String name) { this.name = name; }
4 String getName() { return name; }
5}
6 class Finder {
7 Person findPerson() {
8 return null; //Intentionally returning null
9 }
10 String getName() {
11 Person person = findPerson();
12 if (person != null) {
13 return person.getName();
14 }
15 return "Unknown";
16 }
17 }
18 public class Main {
19 public static void main(String[] args) {
20 Finder finder = new Finder();
1
21 System.out.println(finder.getName());
22 }
23 }
Output: Unknown Problem: Extra checks for missing values.
With Optional:
1 import java.util.Optional;
2 class Person {
3 String name;
4 Person(String name) { this.name = name; }
5 String getName() { return name; }
6}
7 class Finder {
8 Optional<Person> findPerson() {
9 return Optional.ofNullable(null);
10 }
11 String getName() {
12 return findPerson()
13 .map(Person::getName)
14 .orElse("Unknown");
15 }
16 }
17 public class Main {
18 public static void main(String[] args) {
19 Finder finder = new Finder();
20 System.out.println(finder.getName());
21 }
22 }
Output: Unknown Benefit: Shorter, safer code.
3.2 Example 2: Formatting a City
Without Optional:
1 class Finder {
2 String getCity() {
3 return null;
4 }
5 String formatCity() {
6 String city = getCity();
7 if (city != null && city.length() > 3) {
8 return city.toUpperCase();
9 }
10 return "NONE";
11 }
12 }
13 public class Main {
14 public static void main(String[] args) {
15 Finder finder = new Finder();
16 System.out.println(finder.formatCity());
17 }
18 }
Output: NONE Problem: Messy checks.
With Optional:
1 import java.util.Optional;
2 class Finder {
3 Optional<String> getCity() {
4 return Optional.ofNullable(null);
5 }
6 String formatCity() {
7 return getCity()
8 .filter(city -> city.length() > 3)
9 .map(String::toUpperCase)
10 .orElse("NONE");
11 }
2
12 }
13 public class Main {
14 public static void main(String[] args) {
15 Finder finder = new Finder();
16 System.out.println(finder.formatCity());
17 }
18 }
Output: NONE Benefit: Clear, chained steps.
3.3 Example 3: Handling Missing Data with Errors
Without Optional:
1 class Finder {
2 String getData() {
3 return null;
4 }
5 String fetchData() {
6 String data = getData();
7 if (data == null) {
8 throw new RuntimeException("Data missing");
9 }
10 return data;
11 }
12 }
13 public class Main {
14 public static void main(String[] args) {
15 Finder finder = new Finder();
16 try {
17 System.out.println(finder.fetchData());
18 } catch (RuntimeException e) {
19 System.out.println(e.getMessage());
20 }
21 }
22 }
Output: Data missing Problem: Needs error checks.
With Optional:
1 import java.util.Optional;
2 class Finder {
3 Optional<String> getData() {
4 return Optional.ofNullable(null);
5 }
6 String fetchData() {
7 return getData()
8 .orElseThrow(() -> new RuntimeException("Data missing"));
9 }
10 }
11 public class Main {
12 public static void main(String[] args) {
13 Finder finder = new Finder();
14 try {
15 System.out.println(finder.fetchData());
16 } catch (RuntimeException e) {
17 System.out.println(e.getMessage());
18 }
19 }
20 }
Output: Data missing Benefit: Simple error handling.
4 Tips for Using Optional
4.1 Do These
• Use Optional for methods that might return nothing.
3
• Use orElse or orElseGet, not get().
• Use map and filter for clean code.
4.2 Avoid These
• Don’t use get(); it may fail.
• Don’t use Optional everywhere.
• Don’t nest Optional; use flatMap.
5 Practice Tasks
1. Get a persons age:
• Without Optional: Use checks, default 0.
• With Optional: Use map, orElse(0).
2. Format a name to uppercase:
• Without Optional: Check if name exists.
• With Optional: Use map, orElse.
3. Throw error for missing address:
• Without Optional: Check and throw.
• With Optional: Use orElseThrow.
6 Resources
• https://www.baeldung.com/java-optional
• https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html