更新时间:
#Java 8 Optional正确使用
optional: 可以帮我们把判空的代码写得更优雅
原来解决方案: 我们首先要判断这个返回值是否为null,只有在非空的前提下才能将其作为其他方法的参数。这正是一些类似Guava的外部API试图解决的问题。
一些JVM编程语言比如Scala、Ceylon等已经将对在核心API中解决了这个问题。
#构造
//调用工厂方法创建Optional实例
Optional name = Optional.of("Sanaulla");
//传入参数为null,抛出NullPointerException.
Optional someNull = Optional.of(null);
为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。
Optional empty = Optional.ofNullable(null);
https://blog.csdn.net/boling%5Fcavalry/article/details/77610629
if (name.isPresent()) {
//在Optional实例内调用get()返回已存在的值
System.out.println(name.get());//输出Sanaulla
}
这种写法就是不优雅的,跟原先判断 !=null 啥区别
#optional意义:
- 用在函数上,让调用者必须去判断空否
- 用在空对象处理上, 但结合着lambda用
#ifPresent 和 orElse orElseGet orElseThrow
如果Optional实例有值则为其调用consumer,否则不做处理.
要理解ifPresent方法,首先需要了解Consumer类。简答地说,Consumer类包含一个抽象方法。该抽象方法对传入的值进行处理,但没有返回值。
如果Optional实例有值,调用ifPresent()可以接受接口段或lambda表达式。类似下面的代码:
//ifPresent方法接受lambda表达式作为参数。
//lambda表达式对Optional的值调用consumer进行处理。
name.ifPresent((value) -> {
System.out.println("The length of the value is: " + value.length());
return “adf”;//此处不可以有返回值
});
System.out.println(empty.orElse("There is no value present!"));
orElseGet与orElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值。示例如下:
System.out.println(empty.orElseGet(() -> "Default Value"));
在orElseGet方法中,我们传入一个Supplier接口。然而,在orElseThrow中我们可以传入一个lambda表达式或方法,如果值不存在来抛出异常。示例如下:
empty.orElseThrow(ValueAbsentException::new);
#map flatmap
如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。
map方法用来对Optional实例的值执行一系列操作。通过一组实现了Function接口的lambda表达式传入操作。map方法示例如下:
//map方法执行传入的lambda表达式参数对Optional实例的值进行修改。
//为lambda表达式的返回值创建新的Optional实例作为map方法的返回值。
Optional upperName = name.map((value) -> value.toUpperCase());
System.out.println(upperName.orElse("No value found"));
Optional any = getAutoUsedGoodsSkill(effect);
return any.map(u->Float.parseFloat(u.getMsg()))
.orElse(0F);
// if (any.isPresent()) {
// return Float.parseFloat(any.get().getMsg());
// }
// return 0;
flatmap 如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。flatMap与map(Funtion)方法类似,区别在于flatMap中的mapper返回值必须是Optional。调用结束时,flatMap不会对结果用Optional封装。
//flatMap与map(Function)非常类似,区别在于传入方法的lambda表达式的返回类型。
//map方法中的lambda表达式返回值可以是任意类型,在map函数返回之前会包装为Optional。
//但flatMap方法中的lambda表达式返回值必须是Optionl实例。
upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
System.out.println(upperName.orElse("No value found"));//输出SANAULLA
#filter
Optional<String> anotherName = Optional.of("Sana");
Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);
//输出:name长度不足6字符
System.out.println(shortName.orElse("The name is less than 6 characters"));
public String getStudentUpperName(int id){
Optional<Student> optional = Optional.ofNullable(queryById(id));
return optional.map(student -> student.getName())
.map(name -> name.toUpperCase())
.orElse("invalid");
}
public Student getStudent(int id){
Optional<Student> optional = Optional.ofNullable(queryById(id));
//如果为空就返回DEFAULT对象
return optional.orElseGet(() -> getDefault());
}