网站首页 > java教程 正文
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-03 支付宝一面:多线程事务怎么回滚?用 @Transactional可以回去了!
- 2025-08-03 算法设计技巧之回溯法(Java实现N皇后问题)
- 2025-08-03 FreeMarker 语法全面详解
- 2025-08-03 OpenJDK16 ZGC 源码分析
- 2025-08-03 我的世界内存错误解决方法详解
- 2025-08-03 如何优雅的实现Mysql 增删改查,看完你就会了
- 2025-08-03 从源码全面解析 dubbo 消费端服务调用的来龙去脉
- 2025-08-03 刷完这49题,面试官当场给Offer!Java程序员必备指南
- 2025-08-03 通过 HTTP/2 协议案例学习 Java & Netty 性能调优:工具、技巧与方法论
- 2025-08-03 用Axure 实现“打飞机”,骚年,来一发(上)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)