【从零单排】浅析Java 8新功能Optional
初识
A container object which may or may not contain a non-null value.
笔者理解,Optional是一个容器类。将Object放到Optional中,从而可以使用容器的一些特性,比如链式编程(Stream)等。
具体应用起来,可以分为两步:
- 放入容器
- 使用容器
放入容器
有两个方法可以使用,第一个of
,不检查传入value是否为null,可能会报NPE。
第二个ofNullable
会检查,如果value为null,就返回一个empty的Optional,不会NPE。
static <T> Optional<T> of(T value)
static <T> Optional<T> ofNullable(T value)
容器方法分析
map
和filter
功能差不多,对目标Object做某种操作(Function),或者做某种比较(Pridicate),最后返回符合要求的Optional值,不符合的话就是Empty,不会NPE。
<U> Optional<U> map(Function<? super T,? extends U> mapper)
// If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result.
// Otherwise return an empty Optional.
Optional<T> filter(Predicate<? super T> predicate)
// If a value is present, and the value matches the given predicate, return an Optional describing the value,
// otherwise return an empty Optional.
ifPresent
也是保证不会NPE的,如果value有值,就做某操作,否则什么都不做。
void ifPresent(Consumer<? super T> consumer)
// If a value is present, invoke the specified consumer with the value, otherwise do nothing.
使用容器
最最最常用的:不写那么多if null
的代码,而是用Optional的特性保证不会NPE。
示例1:一层 if 判断
// OLD
if (student != null) {
doSomething(student);
}
// NEW
Optional.ofNullable(student).ifPresent(s -> doSomething(s.getName()));
示例2:两层 if 判断
// OLD
if (student != null) {
if (student.getName() != null) {
doSomething(student.getName().trim());
}
}
// NEW
Optional.ofNullable(student)
.map(s -> s.getName())
.ifPresent(name -> doSomething(name.trim()));
Optional.ofNullable(student)
.map(Student::getName)
.ifPresent(name -> doSomething(name.trim()));
Optional.ofNullable(student)
.ifPresent(s -> Optional.ofNullable(s.getName())
.ifPresent(name -> doSomething(name.trim())));
示例3:没有返回值,则返回默认值
Optional.ofNullable(list_a).orElse(new ArrayList());
示例4:没有返回值,则抛出异常
try {
Optional.ofNullable(list_a).orElseThrow(Exception::new);
} catch (Exception e) {
e.printStackTrace();
}
总结
Optional和Stream,感觉一是要慢慢去熟悉这种代码风格,二是适合于逻辑不那么复杂的场景。