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 (student != null) { System.out.println("一般方法:" + student.getName()); }
Optional<Student> optionalStudent = Optional.ofNullable(student); 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);
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 { 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") Optional<U> r = (Optional<U>) mapper.apply(value); return Objects.requireNonNull(r); } }
|