Skip to content

Commit 27b6662

Browse files
committed
Changed some prerequisites names.
1 parent 8f2afa8 commit 27b6662

File tree

5 files changed

+158
-1
lines changed

5 files changed

+158
-1
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"blurb": "Learn to use the Optional class by helping Tim print details of his company employees.",
3+
"authors": [
4+
"josealonso"
5+
],
6+
"contributors": [
7+
"kahgoh"
8+
]
9+
}

concepts/optional-type/about.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# About the Optional Type
2+
3+
The **Optional<T>** type was introduced in Java 8 as a way to indicate that a method _may_ return a value.
4+
5+
Before Java 8, developers had to implement null checks:
6+
7+
```java
8+
public Employee getEmployee(String name) {
9+
// Assume that getEmployeeByName retrieves an Employee from a database
10+
Employee employee = getEmployeeByName(name);
11+
if (employee != null) {
12+
return employee;
13+
} else {
14+
throw new IllegalArgumentException("Employee not found");
15+
}
16+
}
17+
```
18+
19+
With the Optional API, the code above can be simplified to:
20+
21+
```java
22+
public Optional<Employee> getEmployee(String name) {
23+
// Assume that getEmployeeByName returns an Optional<Employee>
24+
return getEmployeeByName(name)
25+
.orElseThrow(() -> new IllegalArgumentException("Employee not found"));
26+
}
27+
```
28+
29+
## Usage with the Stream API
30+
31+
The Optional API is more useful when many methods are chained and each method returns an Optional<T> object.
32+
33+
```java
34+
List<Optional<Employee>> employees = new ArrayList<>();
35+
employees.add(getEmployee("Tim"));
36+
employees.add(getEmployee("Bob"));
37+
employees.add(getEmployee("Alice"));
38+
```
39+
40+
```java
41+
public List<Optional<Employee>> getEmployeesInTheirTwenties(){
42+
return employees.stream()
43+
.filter(Optional::isPresent)
44+
.map(Optional::get)
45+
.filter(employee -> employee.getAge() >= 20 && employee.getAge() < 30)
46+
.collect(Collectors.toList());
47+
}
48+
```
49+
50+
It is important to understand that the Optional API does not eliminate the null checking,
51+
but it defers it until the end of a series of methods, as long as all those methods return an optional object.
52+
53+
## Recommended usage
54+
55+
The Optional type is mainly used as returned type. Using it as a parameter type or field type is less common and
56+
not recommended, as explained by one well-known Java language architect in [this SO answer](https://stackoverflow.com/questions/26327957/should-java-8-getters-return-optional-type)
57+
58+
The official documentation says:
59+
> Optional is primarily intended for use as a method return type where there is a clear need to represent "no result," and where using null is likely to cause errors. A variable whose type is Optional should never itself be null; it should always point to an Optional instance.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Introduction
2+
3+
## Optional
4+
5+
The **Optional<T>** type was introduced in Java 8 as a way to indicate that a method _may_ return a value.
6+
7+
In other words, there is a chance the method returns "no value" at all.
8+
9+
## Creating an Optional<T> object
10+
11+
Given an object of type Employee, an Optional<Employee> object can be created using the static [of][optional-of-javadoc] method:
12+
13+
```java
14+
Employee employee = new Employee();
15+
Optional<Employee> optionalEmployee = Optional.of(employee);
16+
```
17+
18+
If the employee _may_ be not present, the static [ofNullable][optional-ofNullable-javadoc] method must be used:
19+
20+
```java
21+
Employee nullableEmployee = new Employee();
22+
Optional<Employee> nullableEmployee = Optional.ofNullable(employee);
23+
```
24+
25+
`optionalEmployee` and `nullableEmployee` both are wrappers of an `Employee` object.
26+
27+
## Basic methods
28+
29+
If a value is present, the [isPresent][optional-isPresent-javadoc] method returns true and the [get][optional-get-javadoc] method returns the value.
30+
31+
```java
32+
Employee employee = new Employee("Tim", 45);
33+
Optional<Employee> optionalEmployee = Optional.ofNullable(employee);
34+
boolean isThereAnEmployee = optionalEmployee.isPresent(); // true
35+
Employee employee = optionalEmployee.get();
36+
```
37+
38+
## Usage
39+
40+
In order to throw an exception when the value is not present, the [orElseThrow][optional-orElseThrow-javadoc] method must be used.
41+
42+
```java
43+
public Optional<Employee> getEmployee(String name) {
44+
// Assume that getEmployeeByName returns an Optional<Employee>
45+
return getEmployeeByName(name)
46+
.orElseThrow(() -> new IllegalArgumentException("Employee not found"));
47+
}
48+
```
49+
50+
If a default value must be returned, the [orElse][optional-orElse-javadoc] method can be used.
51+
52+
```java
53+
public Optional<Employee> getEmployee(String name) {
54+
// Assume that getEmployeeByName returns an Optional<Employee>
55+
return getEmployeeByName(name)
56+
.orElse(new Employee("Daniel"));
57+
}
58+
```
59+
60+
Other commonly used method is [ifPresentOrElse][optional-ifPresentOrElse-javadoc], which is used to handle both cases with the same method: the case where the value is present and the case where the value is empty.
61+
62+
```java
63+
public Optional<Employee> getEmployee(String name) {
64+
// Assume that getEmployeeByName returns an Optional<Employee>
65+
return getEmployeeByName(name)
66+
.ifPresentOrElse(
67+
employee -> System.out.println(employee.getName()),
68+
() -> System.out.println("Employee not found")
69+
);
70+
}
71+
```
72+
73+
Provided all the invoked methods return Optional objects, many methods can be chained without having to worry about null checking:
74+
75+
```java
76+
public Optional<Integer> getEmployeeAge(String name) {
77+
Optional<Employee> optionalEmployee = getEmployeeByName(name);
78+
return getEmployeeByName(name)
79+
.map(employee -> employee.getAge())
80+
.orElse("No employee found");
81+
}
82+
```
83+
84+
[optional-of-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Optional.html#of(java.lang.Object)
85+
[optional-ofNullable-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Optional.html#ofNullable(java.lang.Object)
86+
[optional-get-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Optional.html#get()
87+
[optional-isPresent-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Optional.html#isPresent()
88+
[optional-orElse-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Optional.html#orElse(T)
89+
[optional-orElseThrow-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Optional.html#orElseThrow()
90+
[optional-ifPresentOrElse-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Optional.html#ifPresentOrElse(java.util.function.Consumer,java.lang.Runnable)

concepts/optional-type/links.json

Whitespace-only changes.

config.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,6 @@
317317
"optional-type"
318318
],
319319
"prerequisites": [
320-
"custom-classes",
321320
"lists",
322321
"generic-types"
323322
]

0 commit comments

Comments
 (0)