java Stream之Optional API
摘要:介绍Stream的容器类中 Optional 方法。
综述
仰慕 Stream 流久矣,终于有机会彻底的了解其特性以及用法了,关于源码的理解还需要持续增加深度。在学习 Stream 的时候,同时认识了强大的 Optional,本文就介绍 Optional 的API。
Optional 是Java 8提供的一个容器类,用来装载可能为空的引用。作为java程序员,经常在业务逻辑中检查对象是否为空,引入Optional可以很友好地解决空指针异常,避免显式进行空值检测,提高代码的可读性和可维护性。
Optional类的API
Optional of(T t)
使用静态方法 of(T t) 创建一个非空的 Optional 对象。注意:传递的参数t必须是非空的,也就是说不能为 null;否则,抛出空指针异常NullPointerException。
Optional ofNullable(T t)
使用静态方法 ofNullable(T t) 创建一个即可空又可非空的 Optional 对象。
Optional可以通过工厂方法of()、ofNullable()和empty()创建实例,示例如下:
// 创建非空的Optional实例
Optional<String> optional = Optional.of(“hello”);
// 创建值为空的的Optional对象
Optional<String> optOrNull = Optional.ofNullable(null);
System.out.println(optOrNull); // 输出:Optional.empty
// 使用静态方法empty()创建空的Optional实例
Optional<String> empty = Optional.empty();
boolean isPresent()
isPresent() 用于判断一个 Optional 对象是否存在值,如果存在,该方法返回 true;否则,返回 false。Java 11 后还可以通过方法 isEmpty() 判断与 isPresent() 相反的结果。
void ifPresent(Consumer<? super T> consumer)
判断是否存在值,如果值存在则使用函数式编程的方式执行 consumer;否则,不做任何事情。如果没有该方法,需要先通过 isPresent() 方法对 Optional 对象进行判空再执行相应的代码:
Optional<String> opt = Optional.of("楼兰胡杨");
opt.ifPresent(str -> System.out.println(str.length()));
T get()
get方法用于获取封装在 Optional 对象中的、不为null的值;若没有,则抛出NoSuchElementException。
T orElse(T other)
orElse(T other) 方法用于获取封装在 Optional 对象中的、不等于null的值,如果调用的对象包含null值,则返回默认值other。
public static void main(String[] args) {
Integer num = null;
Integer orElse = Optional.ofNullable(num).orElse(12);
System.out.println("orElse null: " + orElse);
num = 32;
orElse = Optional.ofNullable(num).orElse(12);
System.out.println("orElse 32: " + orElse);
}
执行结果:
orElse null: 12
orElse 32: 32
T orElseGet(Supplier<? extends T> other)
如果对象包含不为null的值,则返回该值;否则,使用函数式编程的方式触发 other 函数,并返回 other 执行的结果。它与 orElse(T other) 方法类似,但参数类型不同。
Optional<Employee> op = Optional.ofNullable(null);
// 参数是函数式接口,可以写自定义业务逻辑
Employee emp = op.orElseGet(() -> new Employee());
Optional filter(Predicate<? super predicate)
Optional可以实现数据过滤,与Stream流过滤功能如出一辙,也是通过匿名内部类new Predicate实现。filter() 方法的参数类型为 Predicate,也就是说可以将一个 Lambda 表达式传递给该方法作为条件,如果值非空,则根据Predicate断言条件检查该值是否符合预期,若符合则返回包含此值的Optional对象,若不符合则返回一个EMPTY的Optional对象。
public class OptionalMapFilterDemo {
public static void main(String[] args) {
String password = "password";
Optional<String> opt = Optional.ofNullable(password);
Predicate<String> len6 = pwd -> pwd.length() > 6;
Predicate<String> len10 = pwd -> pwd.length() < 10;
Predicate<String> eq = pwd -> pwd.equals("password");
boolean result = opt.map(String::toLowerCase).filter(len6.and(len10 ).and(eq)).isPresent();
System.out.println(result);
// filter提供一个断言,过滤Optional的值
Optional<List<Integer>> integers = Optional.ofNullable(Arrays.asList(1, 2, 3, 4, 5)).filter(list -> list.size() > 5);
}
//过滤List中null的元素
public <T> List<T> filterNullElem(Iterable<T> target) {
return ofNullable(target).filter(Objects::nonNull).collect(Collectors.toList());
}
}
filter 与orElse或者orElseGet联合使用案例:
// 如果filter函数返回的Optional值为null,那么返回orElse方法中的值
String v1 = Optional.of("").filter(e -> e != null && e.length() > 0).orElse("default");
System.out.println(v1);
// orElseGet提供一个生成器,用于返回默认值
String v2 = Optional.of("").filter(e -> e != null && e.length() > 0).orElseGet(() -> "123");
System.out.println(v2);
Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
如果值存在,返回映射方法mapper的值;否则,返回一个空的Optional。
Optional<U> map(Function<? super T, ? extends U> mapper)
就像stream流一样,Optional也可以通过map的方式从Optional中取出元素,map方法返回的是一个Optional类型的对象,里面的值如果为null,可以使用orElse方法赋上自定义的默认值。
Insurance insurance = new Insurance();
insurance.setName("楼兰胡杨");
Optional<Insurance> optionalInsurance = Optional.ofNullable(insurance);
String name = optionalInsurance.map(Insurance::getName).orElse("unKnown");
如果有值,则对其执行映射函数mapper得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值;否则,返回空Optional。
T orElseThrow(Supplier<? extends X> exceptionSupplier)
如果存在值,返回包含的值;否则,抛出由 exceptionSupplier 指定的异常:
String v3 = Optional.of("").filter(e -> e != null && e.length() > 0).orElseThrow(RuntimeException::new);
Reference
- https://www.cnblogs.com/his365/p/17301615.html
- https://blog.csdn.net/weixin_46263782/article/details/121237366
java Stream之Optional API的更多相关文章
- Java Stream API性能测试
已经对Stream API的用法鼓吹够多了,用起简洁直观,但性能到底怎么样呢?会不会有很高的性能损失?本节我们对Stream API的性能一探究竟. 为保证测试结果真实可信,我们将JVM运行在-ser ...
- 恕我直言你可能真的不会java第2篇:Java Stream API?
一.什么是Java Stream API? Java Stream函数式编程接口最初是在Java 8中引入的,并且与lambda一起成为Java开发的里程碑式的功能特性,它极大的方便了开放人员处理集合 ...
- Java Stream 使用详解
Stream是 Java 8新增加的类,用来补充集合类. Stream代表数据流,流中的数据元素的数量可能是有限的,也可能是无限的. Stream和其它集合类的区别在于:其它集合类主要关注与有限数量的 ...
- map和flatmap的区别+理解、学习与使用 Java 中的 Optional
转自:map和flatmap的区别 对于stream, 两者的输入都是stream的每一个元素,map的输出对应一个元素,必然是一个元素(null也是要返回),flatmap是0或者多个元素(为n ...
- 理解、学习与使用 Java 中的 Optional
从 Java 8 引入的一个很有趣的特性是 Optional 类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) -- 每个 Java 程序员都 ...
- 理解、学习与使用 JAVA 中的 OPTIONAL<转>
从 Java 8 引入的一个很有趣的特性是 Optional 类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...
- 如何更好地使用Java 8的Optional
Java 8中的Optional<T> 是一个可以包含或不可以包含非空值的容器对象,在 Stream API中很多地方也都使用到了Optional. java中非常讨厌的一点就是nullp ...
- java stream collector
Java Stream API进阶篇 本文github地址 上一节介绍了部分Stream常见接口方法,理解起来并不困难,但Stream的用法不止于此,本节我们将仍然以Stream为例,介绍流的规约操作 ...
- 理解、学习与使用 JAVA 中的 Optional【转载】
这是一篇转载的文章.刚学java的时候看了好久这个Optional,但一直是懵的.今天又又遇到了,重新回来再看的时候,发现并没有那么难道那个. 转载的文章再开头处写了一个对于理解Optional很关键 ...
- JAVA 中的Optional (臭名昭著的空指针异常(NullPointerException))
从 Java 8 引入的一个很有趣的特性是 Optional 类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) -- 每个 Java 程序员都 ...
随机推荐
- Chrome设置header请求响应头 Chrome ModHeader插件,添加/修改/删除HTTP请求标头和响应标头
ModHeader,是一款可以添加/修改/删除请求标头和响应标头的浏览器插件. ModHeader插件功能 首先,ModHeader插件支持添加/修改/删除请求标头和响应标头,并可以启用基于URL / ...
- UNIX 系统
UNIX 系统的历史,UNIX 是操作系统的开山鼻祖,是操作系统的发源地,后来的 Windows 和 Linux 都参考了 UNIX. 有人说,这个世界上只有两种操作系统: UNIX 和类 UNIX ...
- Redis 原理 - Set
Set数据结构 使用 intset 当同时满足下面两个条件时,使用 intset 存储数据 元素个数少于512个 (set-max-intset-entries: 512) 所有元素都是整数值 不满足 ...
- 自制一个超级简单的 php 发邮件的轮子 simpleMailTool.php
simpleMailTool 程序链接 https://github.com/kohunglee/simpleMailTool/ 一个简单的 php 发邮件的轮子,跟其他著名大轮子相比(如 PHPMa ...
- BUUCTF---这是Base??
题目 dict:{0: 'J', 1: 'K', 2: 'L', 3: 'M', 4: 'N', 5: 'O', 6: 'x', 7: 'y', 8: 'U', 9: 'V', 10: 'z', 11 ...
- 网络编程-Netty-writeAndFlush方法原理分析 以及 close以后是否还能写入数据?
前言 在上一讲网络编程-关闭连接(2)-Java的NIO在关闭socket时,究竟用了哪个系统调用函数?中,我们做了个实验,研究了java nio的close函数究竟调用了哪个系统调用,答案是clos ...
- Oracle SQL%ROWCOUNT
SQL%ROWCOUNT 用于记录受影响的行数, 必须紧跟在一个新增/修改/删除类语句后. 当执行多条修改语句时, 按照 sql%rowcount 之前执行的最后一条语句受影响行数为准. 应用场景 可 ...
- 使用XML的方式编写:@Aspect运用
例子. 接口 public interface Calculator { // 加 public int add(int i, int j); // 减 public int sub(int i, i ...
- 结合钉钉机器人用python写监控打印机碳粉状态程序
点击查看代码 from pysnmp.hlapi import * import requests import json # 配置信息 PRINTER_IP = '1.1.1.1' # 打印机IP ...
- Win10远程桌面连接功能
Win10远程桌面连接功能 Win10系统自带的远程桌面连接需要满足以下三个条件 开启远程桌面连接 设置一个连接密码 知道自己的IP地址 下面教你如开开启远程设置 第一步:在桌面我的电脑图片上单机属性 ...