网站首页 > 技术文章 正文
Optional 是什么
Optional 是 Java8 引入的一个 容器 ,用于包装可能为 null 的值,它的主要目的是:
1、显示的表示“值可能不存在”
2、强制调用方处理空值的情况
关键方法
声明一个Optional
of(T value)
包装非 null 值,这是个静态方法。 #技术分享
Optional<String> s = Optional.of("Hello world!");
ofNullable(T value)
包装可能为 null 的值,这也是个静态方法。
Optional<String> s = Optional.ofNullable("Hello world!");
empty()
返回一个包装 null 的 Optional
Optional<String> s = Optional.empty();
存在性判断
isPresent()
判断是否有非 null 元素。
Optional<String> s = someMethod();
if (s.isPresent()) { }
isEmpty()
判断是否是 null 元素
Optional<String> s = someMethod();
if (s.isEmpty()) { }
条件执行
ifPresent(Consumer)
如果是非 null 就执行一些操作,是 null 则什么也不做,只是简单的消费者,不能 return 值。
Optional<String> s = someMethod();
s.ifPresent(v -> { System.out.println("current value: " + v); });
ifPresentOrElse(Consumer)
可以同时指定 null 和非 null 两种场景的回调函数。
Optional<String> s = someMethod();
s.ifPresentOrElse(v -> { System.out.println("current value: " + v);
}, () -> { System.out.println("no value present");
});
获取值
get()
直接获取内部的值,如果是 null,则会抛出异常。建议先 isPresent() 先检查是否存在值,再调用 get()
Optional<String> s = someMethod();
if (s.isPresent()) { System.out.println(s.get()); }
orElse(T value)
获取内部的值,如果为 null,则返回给定的默认值。
Optional<String> s = someMethod();
String s1 = s.orElse("Default value");
orElseGet(Supplier)
和 orElse 最终的效果一样。
Optional<String> s = someMethod();
String s1 = s.orElseGet(() -> someComplexMethod());
和 orElse 的区别在于:
1、orElse 是不管 optional 内部是否为 null,都会执行默认方法,适用于默认值为简单常量的场景。
2、orElseGet 会先判断 optional 是否为 null,当为 null 才会执行默认方法
所以如果这样调用就不太好,因为一定会执行复杂的方法,耗费性能:
Optional<String> s = someMethod();
String s1 = s.orElse(someComplexMethod());
orElseThrow(Supplier)
获取值,如果为 null,则抛出给定的异常。
Optional<String> s = someMethod();
String s1 = s.orElseThrow(() -> new RuntimeException("Error!"));
过滤和转换
filter(Predicate)
给定一个判断条件,如果满足条件,则什么也不改变;如果不满足条件,则内部元素被拦截,不会往下游走,也就是变成了 Optional.empty()。
Optional<String> s = someMethod();
Optional<String> s1 = s.filter(v -> v.length() > 5);
map(Function)
这个就好理解了,改变元素的形状或者值。
Optional<Integer> s = someMethod();
Optional<String> s1 = s.map(Object::toString);
Optional<String> s = someMethod();
Optional<String> s1 = s.map(v -> v + "hello");
flatMap(Function)
扁平化转换,处理嵌套的 Optional,可以将 Optional> 转换成 Optional
Optional<String> s = someMethod();
Optional<String> t = s.flatMap(v -> { return Optional.of(v +
});
最佳实践
只使用在方法返回值/null检查
Optional 的目的之一是强制调用方处理空值的情况,所以推荐在方法返回值的时候使用,不要在参数或者对象属性中使用。同时也可以进行 null 检查。
public Optional<String> someMethod() {
return Optional.empty(); }
public void someMethod() { String s = somefun();
String t = Optional.ofNullable(s) .orGet("hello"); }
不要包装集合类型
Optional 已经是一个集合,没必要在包括另外一个集合类型,意义不是很大,如果是空数据,返回空集合即可。
public Optional<List<String>> someMethod() {
List<String> list = new ArrayList<>();
return Optional.ofNullable(list); }
public List<String> someMethod() {
List<String> list = new ArrayList<>();
if (list == null) { return new ArrayList<>(); }
return list; }
避免 isPresent() + get() 的啰嗦写法
这样容易写出命令式代码,不够优雅,并且 Optional 的提出就是为了避免繁琐的 if 判断。
Optional<String> s = someMethod();
if (s.isPresent()) { System.out.println(s.get());
}
而是推荐以下写法:
1、当只是简单的消费数据,不需要 return,推荐使用 ifPresent(Consumer)
Optional<String> s = someMethod();
s.ifPresent(v -> { System.out.println("current value: " + v); });
2、需要 return 值,推荐 map + orElse/orElseGet
public String fun() {
Optional<String> s = someMethod();
if (s.isPresent()) { System.out.println(s.get()); return "anyhow" + s.get(); } return "other"; }
public String fun() { Optional<String> s = someMethod();
return s..map(value -> { System.out.println(value); return "anyhow" + value; }) .orElse("default"); }
猜你喜欢
- 2025-08-05 KKR Nears Completion of Dayao Soda Buyout in Rare Foreign Takeover of Chinese Beverage Brand
- 2025-08-05 The Rise of China’s Machine Tool Industry Despite the West's Export Restrictions
- 2025-08-05 Tesla Logs Largest Revenue Decline in Over A Decade as Q2 EV Sales Continues to Plunge
- 2025-08-05 Chinese vice premier calls for championing humanity's common values, promoting multipolar world
- 2025-08-05 China Unveils 600 km/h Superconducting Maglev Train, Expected to Slash Beijing–Shanghai Travel Time to 2.5 Hours
- 2025-08-05 Partnership can once again prove its mettle
- 2025-08-05 Amundi sees "US Exceptionalism" eroding, while turns bullish on China's AI
- 2025-08-05 China's listed banks attract record investor visits on dividend appeal
- 2025-08-05 Huawei Denies Plagiarism in Pangu AI Model After Allegations of Copying Alibaba's Qwen
- 2025-08-05 US consumers 'eat' force-fed tariffs
- 1522℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 645℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 527℃MySQL service启动脚本浅析(r12笔记第59天)
- 492℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 492℃启用MySQL查询缓存(mysql8.0查询缓存)
- 479℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 461℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 459℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)