本文简单介绍 Java 8 中 Optional
的最常用法。
创建 Optional
创建 Optional
有三个方法,如下所示:
// 方法1:参数不能为 null,否则会抛出异常
Optional<String> stringOptional = Optional.of("success");
// 方法2:无法确定参数是否为 null 时,使用这个方法
Optional<String> appNameOptional = Optional.ofNullable(System.getProperty("AppName"));
// 方法3:需要返回一个不含值的 Optional 对象时,使用这个方法
Optional<String> emptyOptional = Optional.empty();
注意:Optional
对象的值是不可修改的。
在业务逻辑中使用 Optional
判断 Optional 的值是否为空,可以用 isPresent()
方法,例如:
Optional<String> appNameOptional =
Optional.ofNullable(System.getProperty("AppName"));
if (!appNameOptional.isPresent()) {
System.out.println("系统属性 AppName 不存在。");
}
但 Optional
设计出来并不是这么用的。标准的用法应该是用 ifPresent()
方法。如下所示:
Optional.ofNullable(System.getProperty("AppName"))
.ifPresent(appname -> System.out.println("AppName = " + appname));
这样的语句比 if 判断简洁的多。
Java 8 的 Optional
类并没有 ifNotPresent()
这样的方法。不过,这个遗憾 在 Java 9 中得到了补足。
从 Optional 对象取值
最简单的取值方法就是 get()
方法了,不用什么例子就看得懂。但同样,Optional
设计出来并不是这么用的。Optional
有更好的取值方法 orElse()
和 orElseGet()
,它们甚至用来代替 if 语句:
// 当系统属性 AppName 不存在时,返回 "DefaultAppName"
String appName = Optional
.ofNullable(System.getProperty("AppName"))
.orElse("DefaultAppName");
// 当缺省值需要调用另外的方法获得时,可以这样实现
String appName = Optional
.ofNullable(System.getProperty("AppName"))
.orElseGet(() -> getFromOtherPlace());
此外如果你希望 Optional 为空时抛出异常,可以用 orElseThrow()
方法:
String appName = Optional
.ofNullable(System.getProperty("AppName"))
.orElseThrow(() -> new IllegalStateException("AppName is empty"));
生成新的 Optional
前面提到 Optional
的值是不可以改的,但如果当前 Optional
对象的内容不是我想要的怎么办? Optional
提供了几个方便的方法,如下所示:
// map() 方法根据当前 Optional 的值生成一个新的 Optional
Optional<String> message = Optional
.ofNullable(System.getProperty("AppName"))
.map(appname -> "App name is " + appname);
// filter() 方法检查 Optional 的值是否满足条件,如果
// 满足则返回自身,否则返回 Optional.empty()
Optional<String> message = Optional
.ofNullable(System.getProperty("AppName"))
.filter(appname -> appname.length() > 0);
综合示例:
下面是一个没有用 Optional
的例子:
List<String> searchResults = Collections.emptyList();
String keyword = parameters.get("keyword");
if (keyword != null) {
String fixedKeyword = "%" + keyword.toUpperCase() + "%";
searchResults = search(fixedKeyword);
}
System.out.println("搜索结果:" + searchResults.size() + " 个");
用了 Optional
之后:
List<String> searchResults = Optional
.ofNullable(parameters.get("keyword"))
.map(keyword -> "%" + keyword.toUpperCase() + "%")
.map(fixedKeyword -> search(fixedKeyword))
.orElse(Collections.emptyList());
System.out.println("搜索结果:" + searchResults.size() + " 个");
当然,上面这个例子中,两个 map()
方法可以写在一起,这个可以根据自己的喜好来了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。