Optional的使用

Optional 被设计出来,主要是为了解决空指针异常

以一个 Student 类为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Getter
class Student {
private String name;
private int age;
private int score;

public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}

public Student() {
}
}

代替 if 语句判空

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void optionalBasicUsage(Student student) {
// if 语句判空
if (student != null) {
System.out.println("一般方法:" + student.getName());
}

// 使用 Optional 无需判空
Optional<Student> optionalStudent = Optional.ofNullable(student);
// 如果Name存在,执行一段逻辑
optionalStudent.map(Student::getName).ifPresent(this::callOther);
}

private Object callOther(String name) {
LOGGER.info("call other api {}...", name);
return null;
}

判空时,通过 orElseGet 方法进行懒加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void optionalAdvanceUsage(Student student) {
Optional<Student> optionalStudent = Optional.ofNullable(student);
// 如果存在,执行一段逻辑
optionalStudent.ifPresent(this::callOther);

// orElseGet实行懒加载,orElse不会懒加载,因此orElseGet性能更好
// Student student1 = optionalStudent.orElse(createStudent());
Student student1 = optionalStudent.orElseGet(this::createStudent);
}

private Student createStudent() {
LOGGER.info("called from createStudent");
return new Student();
}

private Object callOther(Student student) {
LOGGER.info("call other api {}...", student);
return null;
}

使用 filter 进行过滤

1
2
3
4
5
6
7
8
9
public void optionalAdvanceUsage(Student student) {
Optional<Student> optionalStudent = Optional.ofNullable(student);
// 如果存在,执行一段逻辑
optionalStudent.ifPresent(this::callOther);

// 过滤
optionalStudent.filter(stu -> stu.getAge() > 10)
.ifPresent(stu -> LOGGER.info("age > 10 {}", stu.getName()));
}

map 和 flatMap 方法

1
2
3
4
5
6
7
8
9
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
// Optional.ofNullable 会自动在外层用Optional进行封装
return Optional.ofNullable(mapper.apply(value));
}
}
1
2
3
4
5
6
7
8
9
10
11
public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
@SuppressWarnings("unchecked")
// mapper的apply方法要求返回值类型是Optional<? extends U>,所以无需再用Optional封装
Optional<U> r = (Optional<U>) mapper.apply(value);
return Objects.requireNonNull(r);
}
}