# Optional
# 概述
我们在编写代码会经常遇到空指针异常,所以在很多情况下我们需要各种非空判断
Author author = getAuthor(); | |
if(author!=null){ | |
System.out.println(author.getName()); | |
} | |
Author author = getAuthor(); | |
if(author!=null){ | |
System.out.println(author.getName()); | |
} |
对象属性也是对象的话会更多
JDK8 引入 Opitional,可以写出更好的代码来避免空指针异常。
很多函数式编程相关 Api 会用到 Optional
# 使用
public Author getAuthor() { | |
Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null); | |
return author; | |
} |
# 传统使用
Author author = getAuthors(); | |
if (author != null) { | |
System.out.println(author.getName()); | |
} |
# Optional
Optional 的静态方法 ofNullable(T value)
将数据封装成一个 Optional 对象,传入参数为空也没问题
// 源码 | |
public static <T> Optional<T> ofNullable(T value) { | |
return value == null ? empty() : of(value); | |
} |
Optional<Author> optionalAuthor = Optional.ofNullable(author) | |
optionalAuthor.ifPresent(author1 -> System.out.println(author1.getName())); |
也可以使用方法直接返回 Optional 的值
public Optional<Author> getAuthor() { | |
Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null); | |
return Optional.ofNullable(author); | |
} | |
@Test | |
public void testOp(){ | |
Optional<Author> optionalAuthor = getAuthor(); | |
optionalAuthor.ifPresent(author1 -> System.out | |
.println(author1.getName())); | |
} |
实际开发中,很多数据是从数据库获取,Mybatis3.5 版本已经支持 Optional 了,可以直接把 dao 层方法返回 值 类型定义成 Optional 类型 ,Mybatis 会自动将数据封装成对象后返回,封装的过程中不需要自己操作。
# 安全消费值
调用 Optional 对象的 ifPresent()
方法,参数类型 Consumer<? super T>
可以使用 Lambda 表达式。
# 安全获取值
安全的获取值应当避免使用 get () 方法而是使用以下两种方法 :
orElseGet
获取数据并设置数据为空时的默认值,如果数据不为空就能获取到该数据,如果为空则根据你传入的参数来创建对象作为默认值返回
Optional<Author> authorOptional = Optional.ofNullable(getAuthor()); Author author1 = authorOptional.orElseGet(()->new Author());
orElseThrow
获取数据,如果数据不为空就能获取该数据。如果为空则根据你传入的参数来创建异常抛出
try {
author = optionalAuthor.orElseThrow(new Supplier<Throwable>() {
@Override
public Throwable get() {
return new RuntimeException("???");
}
});
} catch (Throwable e) {
e.printStackTrace();
}
# 过滤数据 filter
Author author1 = getAuthor().filter(author -> author.getAge()>10).orElseGet(() -> new Author(0L, "没没没名字", 0, "???", null)); |
# 判断 isPresent ()
判断 Optional 的值是否为空,如果不为空返回 true,为空返回 false
更推荐 ifPresent () 方法
# 数据转换
Optional 提供 map 可以进行数据转换
Optional<Author> author = getAuthor(); | |
Optional<List<Book>> books = author.map(author1 -> author1.getBooks()); | |
books.ifPresent(books1 -> books1.forEach(System.out::println)); |