Optional
1 概述
参考如下代码。
private static void test27() {
Author author = getAuthor();
System.out.println(author.getName());
}
private static Author getAuthor() {
new Author(3L, "cc", 17, "小米最棒", null);
return null;
}
报错NullPointerException
。在实际工作中,如果持久层中存储了一些对象数据,取出时不做判空操作就可能出现空指针异常。
判空的对象如果很多,代码容易疏漏,也不优雅。
private static void test27() {
Author author = getAuthor();
if (author!=null) {
System.out.println(author.getName());
}
}
因此,为了避免出现空指针异常,java8设计了Optional
类.
2 使用
2.1 创建
private static void test28() {
Author author= getAuthor();
Optional<Author> authorOptional = Optional.ofNullable(author);
authorOptional.ifPresent(author1 -> System.out.println(author1.getName()));
}
不过这样的代码似乎也不简洁呀。实际上,我们会这么用。
private static Optional<Author> getAuthor() {
Author author = new Author(3L, "cc", 17, "小米最棒", null);
return Optional.ofNullable(author);
}
private static void test28() {
getAuthor().ifPresent(author1 -> System.out.println(author1.getName()));
}
养成使用Optional
的习惯以后,就不用记忆哪个类需要非空判断了。而且生产中一些框架,如mybatis3.5+
会帮我们完成数据封装的步骤,我们只需要直接使用。
还可以Optional.of()方法创建对象,但是这还是可能出现空指针异常,不推荐。
2.2 安全的消费值
前面的ifpresent
就可以安全的消费值。
private static void test28() {
getAuthor().ifPresent(author1 -> System.out.println(author1.getName()));
}
2.3 安全的获取值
运行如下代码。
private static void test29() {
getAuthor().get();
}
private static Optional<Author> getAuthor() {
return Optional.ofNullable(null);
}
报错:java.util.NoSuchElementException: No value present
。使用OrElseGet
可以设置无数据时返回的默认值。
private static void test29() {
getAuthor().orElseGet(() -> new Author());
}
当然,也可以使用OrElseThrow
在得不到值抛出异常,进行统一处理等。
private static void test30() {
try {
getAuthor().orElseThrow(() -> new RuntimeException("老哥你没有值啊!"));
} catch (Throwable e) {
e.printStackTrace();
}
}
2.4 过滤
Optinal对象的过滤与流的过滤特别类似。
private static void test31() {
Optional<Author> authorOptional = getAuthor().filter(author -> author.getAge() > 15);
authorOptional.ifPresent(System.out::println);
}
2.5 判断
private static void test32() {
Optional<Author> author = getAuthor();
if(author.isPresent()) {
System.out.println(author.get().getName());
}
}
更推荐使用ifPresent
.
2.6 数据转换
使用map()
,与Stream
流很类似。
private static void test33() {
Optional<String> name = getAuthor().map(author -> author.getName());
name.ifPresent(System.out::println);
}