Optional使用
程序员文章站
2022-06-08 10:18:30
...
Optional使用总结
@Test
public void testGuavaOptional(){
/**
* of:
* 为非null的值创建一个Optional。
* of方法通过工厂方法创建Optional类。需要注意的是,创建对象时传入的参数不能为null。如果传入参数为null,则抛出NullPointerException 。
*/
//调用工厂方法创建Optional实例
Optional<String> optional = Optional.of("optional");
if (optional.isPresent()) {
System.out.println(optional.get());
}
//传入参数为null,抛出NullPointerException.
// Optional<String> someNull = Optional.of(null);
/**
* ofNullable:
* 为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。
* ofNullable与of方法相似,唯一的区别是可以接受参数为null的情况。示例如下:
*/
//下面创建了一个不包含任何值的Optional实例
//例如,值为'null'
// 等同Optional.empty();
Optional<String> empty = Optional.ofNullable(null);
/**
* ifPresent:
* 如果Optional实例有值则为其调用consumer,否则不做处理
* 如果Optional实例有值,调用ifPresent()可以接受接口段或lambda表达式。类似下面的代码:
*/
//ifPresent方法接受lambda表达式作为参数。
//lambda表达式对Optional的值调用consumer进行处理。
empty.ifPresent(System.out::println);
/**
* orElse:
* 如果有值则将其返回,否则返回指定的其它值。
* 如果Optional实例有值则将其返回,否则返回orElse方法传入的参数。示例如下:
*/
//如果值不为null,orElse方法返回Optional实例的值。
//如果为null,返回传入的消息。
//输出:There is no value present!
System.out.println(empty.orElse("There is no value present!"));
//输出:optional
System.out.println(optional.orElse("There is some value!"));
/**
* orElseGet
* orElseGet与orElse方法类似,区别在于得到的默认值。
* orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值。示例如下:
*/
//orElseGet与orElse方法类似,区别在于orElse传入的是默认值,
//orElseGet可以接受一个lambda表达式生成默认值。
//输出:Default Value
System.out.println(empty.orElseGet(() -> "Default Value"));
//输出:optional
System.out.println(optional.orElseGet(() -> "Default Value"));
/**
* orElseThrow
* 值不存在则抛出异常,存在则什么不做,有点类似Guava的Precoditions
*/
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);
try {
optional1.orElseThrow(() -> {
throw new IllegalStateException();
});
} catch (Throwable e) {
e.printStackTrace();
}
try {
// 抛出异常
optional2.orElseThrow(() -> {
throw new IllegalStateException();
});
} catch (Throwable e) {
e.printStackTrace();
}
/**
* map: 如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。
* map方法示例如下
*/
//map方法执行传入的lambda表达式参数对Optional实例的值进行修改。
//为lambda表达式的返回值创建新的Optional实例作为map方法的返回值。
Optional<String> upperName = optional.map(String::toUpperCase);
System.out.println(upperName.orElse("No value found"));
System.out.println(optional.map(String::toUpperCase).orElse("啥也没有"));
// 初始化两个对象,
Optional<Login> optionalLogin = Optional.ofNullable(new Login().setId(1).setPassword("123").setUser("小米"));
Optional<Login> optionalNull = Optional.empty();
// 对象不为空,密码修改为123456,并且打印json
System.out.println(optionalLogin.map(login -> login.setPassword("123456")).orElse(new Login().setPassword("000000")));
System.out.println("对象不为空打印:" + optionalLogin.map(JSONObject::toJSONString).orElse(null));
// 对象为空,只生成带id的对象,并且打印json
Login defaultUser = new Login().setId(123456).setUser("654321");
System.out.println(optionalNull.map(login -> login.setPassword("123456")).orElse(defaultUser));
System.out.println("对象为空打印:" + optionalNull.map(JSONObject::toJSONString).orElse(null));
/**
* flatMap:
* 如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。
* flatMap与map(Funtion)方法类似,区别在于flatMap中的mapper返回值必须是Optional。调用结束时,flatMap不会对结果用Optional封装。
* flatMap方法与map方法类似,区别在于mapping函数的返回值不同。map方法的mapping函数返回值可以是任何类型T,而flatMap方法的mapping函数必须是Optional。
* 参照map函数,使用flatMap重写的示例如下:
*/
//flatMap与map(Function)非常类似,区别在于传入方法的lambda表达式的返回类型。
//map方法中的lambda表达式返回值可以是任意类型,在map函数返回之前会包装为Optional。
//但flatMap方法中的lambda表达式返回值必须是Optionl实例。
upperName = optional.flatMap((value) -> Optional.of(value.toUpperCase()));
System.out.println(upperName.orElse("No value found"));//输出SANAULLA
/**
* filter:
* 如果有值并且满足断言条件返回包含该值的Optional,否则返回空Optional。
* 下面的示例介绍了满足限定条件和不满足两种情况
*/
//filter方法检查给定的Option值是否满足某些条件。
//如果满足则返回同一个Option实例,否则返回空Optional。
Optional<String> longName = optional.filter((value) -> value.length() > 6);
System.out.println(longName.orElse("The optional is less than 6 characters"));//输出optional
//另一个例子是Optional值不满足filter指定的条件。
Optional<String> anotherName = Optional.of("haha");
Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);
//输出:name长度不足6字符
System.out.println(shortName.orElse("The optional is less than 6 characters"));
/**
* Optional正确姿势
*/
UserInfo userInfo = new UserInfo().setEmail("[email protected]").setPhone("0987654321").setLogin(new Login().setId(123).setUser("123").setPassword("123"));
// 再把userInfo置空试试:
// userInfo = null;
// java8之前写法
if (null != userInfo){
Login login = userInfo.getLogin();
if (null != login){
String user = login.getUser();
System.out.println(user);
}
}
// Optional写法,是不是感觉顺眼多了
System.out.println(Optional.ofNullable(userInfo).map(UserInfo::getLogin).map(Login::getUser).orElse(null));
}
@Data
@Accessors(chain = true)
private class UserInfo implements Serializable{
private static final long serialVersionUID = 1L;
private String email;
private String phone;
private BaseTest.Login login;
}
@Data
@Accessors(chain = true)
private class Login implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String user;
private String password;
}
推荐阅读
-
四种常用虚拟机安装使用教程汇总介绍(VMware/Virtual_PC/Hyper-V/VirtualBox)
-
使用四叶草Clover安装OS X小牛教程图文介绍
-
focusky动画演示大师艺术图形怎么插入使用?
-
360健康精灵使用教程(保护眼睛刻不容缓)
-
得力封箱器802使用图文方法
-
硬盘能识别可是无法使用是怎么回事原因分析及解决
-
如何使用B计划数据恢复软件恢复格式化电影文件
-
Parallels Desktop 9怎么用?Parallels Desktop 9使用教程介绍
-
linux top命令详解和使用实例及使用技巧(监控linux的系统状况)
-
ZBrush怎么使用Layers绘制层功能?