Optional在Java 8中引入,目的是解决 NullPointerExceptions的问题。 它可以保存类型T的值,代表这个值存在。或者仅仅保存null,表示这个值不存在。原来用 null 表示一个值不存在, Optional 可以更好的表达这个概念。并且可以避免空指针异常。这样我们就不用显式进行空值检测。
一、构建Optional对象(Optional.of(T value) 或Optional.ofNullable(T value))
Optional.of(T value):构造一个Optional对象,入参必须不会空,如果入参是空,就抛出空指针异常。
Optional.ofNullable(T value):构造一个Optional对象,入参可以是空,如果入参是空,就返回Optional.empty()。
Optional<String> optional = Optional.of("MyOptionalTest");
Optional<String> optionalValue = Optional.ofNullable("这个世界是美好的!");
Optional.of(new Empl("1111","测试人员1", "男"))
二、获取Optional对象的值
Optional<String> optional = Optional.of("MyOptionalTest");
String str=optional.get();
三、ifPresent():如果 Optional 对象中的值存在,则会执行该参数实例的 accept 方法,并传入 Optional 中包含的值,否则不做任何操作。
Optional<String> optionalValue = Optional.ofNullable("这个世界是美好的!");
Optional<Integer> lengthOptional = optionalValue.map(String::length);
lengthOptional.ifPresent(len -> System.out.println("Length is: " + len));
四、处理转换操作:map(Function<? super T, ? extends U> mapper):将Optional对象中的值进行转换,并返回一个包含转换结果的新Optional对象。
Optional<String> optionalValue = Optional.ofNullable("这个世界是美好的!");
Optional<Integer> lengthOptional = optionalValue.map(String::length);
补充说明:
map和flatMap的区别:
如果某对象实例的属性本身就为Optional包装过的类型,那么就要使用flatMap方法,
Dept::getEmpl 返回的就是Optional<Empl>类型的,所以不用再使用Optional进行包装,这时就要选用flatMap方法.
对于返回值是其他类型,需要Optional进行包装,如 Empl::getName得到是String类型的, 就需要使用map方法在其外面包装一层Optional对象。个Optional对象,入参可以是空,如果入参是空,就返回Optional.empty()
比如:
public class Dept {
private String name;
private Optional<Empl> empl; //属性为Option封装的Empl对象
public Dept(String name, Optional<Empl> empl) {
this.name = name;
this.empl = empl;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Optional<Empl> getEmpl() {
return empl;
}
public void setEmpl(Optional<Empl> empl) {
this.empl = empl;
}
}
正确写法:
Dept dept=new Dept("测试部",Optional.of(new Empl("1111","测试人员1", "男")));
String emplname= Optional.ofNullable(dept)
.flatMap(Dept::getEmpl)
.map(Empl::getName)
.orElse("false");
System.out.println("emplname===="+emplname);
五、处理过滤操作:filter(Predicate<? super T> predicate):对Optional对象中的值进行过滤操作,返回一个满足条件的Optional对象。
Optional<String> filteredOptional = optionalValue.filter(v -> v.contains("美好"));
filteredOptional.ifPresent(v -> System.out.println("Filtered value is: " + v));
Stream<String> names = Stream.of("张三", "李四", "王二");
Optional<String> nametest = names
.filter(name -> name.startsWith("王"))//过滤出王姓人员
.findFirst();
nametest.ifPresent(name -> {
String s = name.substring(0,1);//对名称进去其他操作
System.out.println("The nametest name is "+ s);
});
六、orElseThrow():该方法获取 Optional 对象中包含的值,如果该值为 null,则抛出指定的异常。
Optional<String> optional1 = Optional.of("11111");
Optional<String> optional2 = Optional.ofNullable(null);
System.out.println(optional1.orElseThrow(() -> new IllegalStateException("can't get value")));
System.out.println(optional2.orElseThrow(() -> new IllegalStateException("can't get value")));
七、orElse():该方法获取 Optional 对象中包含的值,如果该值为 null,则返回指定的默认值。
Optional optional1 = Optional.of("1111");
Optional optional2 = Optional.ofNullable(null);
System.out.println(optional1.orElse("22222"));
System.out.println(optional2.orElse("33333"));