Optional的使用
Optional 被设计出来,主要是为了解决空指针异常。
以一个 Student 类为例:
@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 语句判空
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 方法进行懒加载
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 进行过滤
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 方法
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));
}
}
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);
}
}