Java8 Optional API
Optional API
一、Optional创建方式
前置条件: Insurance对象:
public class Insurance {
private String name;
public String getName() { return name; }
}
1、empty
特点:Usageget()Method时会抛出异常:No value present
范例:
Optional<Insurance> emptyOptional = Optional.<Insurance>empty();
Usageget()Get结果:抛出异常
emptyOptional.get();
输出结果:
Exception in thread "main" java.util.NoSuchElementException: No value present
at java.base/java.util.Optional.get(Optional.java:148)
2、of
特点:Usageget(),不会抛异常
范例:
Optional<Insurance> ofInsurance = Optional.of(new Insurance());
ofInsurance.get();
3、ofNullable
特点:上面两者综合,为null是掉empty,不为空调of。
3.1、为null时,调get()抛出异常 范例:
Optional<Insurance> ofNullableOptionalNull = Optional.ofNullable(null);
ofNullableOptionalNull.get();
输出结果:
Exception in thread "main" java.util.NoSuchElementException: No value present
3.2、不为null时,调get()不报错 范例:
Optional<Insurance> ofNullableOptionalNotNull = Optional.ofNullable(new Insurance());
ofNullableOptionalNotNull.get();
二、orElseGet、orElse、orElseThrow
不管那种方式Create,都适用这几个Method。
1、orElseGet
说明:不为null就Return值,为nullReturn一个构造的对象supplier
范例:
Insurance orElseGetInsurance = ofNullableOptionalNull.orElseGet(Insurance::new);
System.out.println(orElseGetInsurance);
2、orElse
说明:不为null就Return值,否则Return一个引用
范例:
Insurance orElseInsurance = ofNullableOptionalNull.orElse(new Insurance());
System.out.println(orElseInsurance);
3、orElseThrow
说明:不为null就Return值,否则Return一个异常对象
范例:
Insurance orElseThrowInsurance = ofNullableOptionalNull.orElseThrow(RuntimeException::new);
输出结果:抛出Run时异常
Exception in thread "main" java.lang.RuntimeException
at java.base/java.util.Optional.orElseThrow(Optional.java:408)
4、orElseThrow
说明:不为null就Return值,否则Return一个自定义异常对象
范例:
ofNullableOptionalNull.orElseThrow(() -> new RuntimeException("yanxizhu Exception"));
输出结果:抛出自定义异常
Exception in thread "main" java.lang.RuntimeException: yanxizhu Exception
三、filter
先判断传入predicate是否null,让然后判断predicate传入字段是否存在, 不存在:Returnthis。 存在:判断predicate条件是否成立,成立:Returnthis,不成立:Return空。
源码:
public Optional<T> filter(Predicate<? super T> predicate) {
//1、判断传入参数predicate是否为null
Objects.requireNonNull(predicate);
//2、判断t.getName是否存在,
if (!isPresent()) {
//2.1、不存在,返回predicate
return this;
} else {
//2.2、存在:判断predicate条件是否成立,成立返回this,不成立返回empty()
return predicate.test(value) ? this : empty();
}
}
requireNonNull()Source Code:判断传入T是否为null
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
范例:
Usage前CreateOptional对象:
1、创建Optinal,get()会抛出异常
Optional<Insurance> emptyOptional = Optional.<Insurance>empty();
2、of创建,get(),不会抛异常
Optional<Insurance> ofInsurance = Optional.of(new Insurance());
3、ofNullable:上面两者综合
3.1、为null时,调get()抛出异常:No value present
Optional<Insurance> ofNullableOptionalNull = Optional.ofNullable(null);
3.2、不为null时,调get()不报错
Optional<Insurance> ofNullableOptionalNotNull = Optional.ofNullable(new Insurance());
使用demo1:
Optional<Insurance> insurance = emptyOptional.filter(t -> t.getName() == null);
Optional<Insurance> insurance = emptyOptional.filter(t -> t.getName() != null);
insurance.get();
结果: //调用get(),都会Error:No value present: 因为name字段不存在
使用demo2:
范例1:
Optional<Insurance> insurance = ofInsurance.filter(t -> t.getName() == null);
insurance.get();
结果: //不Error,因为name字段存在,且满足name==null
范例2:
Optional<Insurance> insurance = ofInsurance.filter(t -> t.getName() != null);
insurance.get();
结果: //Error,因为name虽然存在,但是name!=null,不成立,会Returnempty空,Usageget()时就会抛出异常:No value present
使用demo3:
Optional<Insurance> insurance = ofNullableOptionalNull.filter(t -> t.getName() != null);
Optional<Insurance> insurance = ofNullableOptionalNull.filter(t -> t.getName() == null);
insurance.get();
结果: //都Error:ofNullableOptional,会走emptyCreate的Optional,字段不存在,直接getGet值为空,Error:No value present
使用demo4:
范例1:
Optional<Insurance> insurance = ofNullableOptionalNotNull.filter(t -> t.getName() == null);
insurance.get();
结果: //不会Error,走ofMethodCreate的Optional,name字段存在,且name==null,所以不Error
范例2:
Optional<Insurance> insurance = ofNullableOptionalNotNull.filter(t -> t.getName() != null);
insurance.get();
结果: //Error,因为虽然name存在,但是name!=null不成立,Returnempty,get()就Error了
filter,Summary:Usage时不确定是否为empty,所以直接UsageofNullableOptionalCreateOptional.
四、map
Usage任何方式Create的Opional,map会将结果再包装成Optionla。 范例:
//map使用
Optional<String> stringOptional = ofNullableOptionalNotNull.map(t -> t.getName());
//有值则返回,没值则返回给定值
System.out.println(stringOptional.orElse("-1"));
//判断值是否存在
System.out.println(stringOptional.isPresent());
//存在值,则打印输出,没有值,不打印。
stringOptional.ifPresent(System.out::println);
五、flatMap
不会将结果再包装成Optional 范例: 前置条件
@Data
public class Cat {
private Optional<Eat> eat;
}
@Data
public class Eat {
private String foodName;
private Integer weight;
}
Usage:
//创建Optional对象
Optional<Cat> cat = Optional.ofNullable(new Cat());
//map将结果包装成Optional
Optional<Optional<Eat>> eat = cat.map(c -> c.getEat());
//flatMap不会
Optional<Eat> eat1 = cat.flatMap(c -> c.getEat());
map与flatMap区别:map将结果包装成Optional,flatMap不会。
六、实列
实列1、Get值之前判断值是否为空
public static String getInsuranceName(Insurance insurance) {
Optional<String> optional = Optional.ofNullable(insurance).map(Insurance::getName);
return optional.orElse("-1");
}
实列2、根据用户拿到保险名字
package com.example.study.java8.optional;
import java.util.Optional;
/**
* 根据用户拿到保险名字
*/
public class NullPointerException {
public static void main(String[] args) {
//肯定会包空指针异常
// String insuranceNameByPerson = getInsuranceNameByPerson(new Person());
//原始写法,做了空指针判断
String insuranceNameByCheckPerson = getInsuranceNameByCheckPerson(new Person());
// System.out.println(insuranceNameByCheckPerson);
//Opional写法
String insuranceNameByOptional = getInsuranceNameByOptional(null);
System.out.println(insuranceNameByOptional);
}
//Opional写法
public static String getInsuranceNameByOptional(Person person) {
return Optional.ofNullable(person)
.map(Person::getCar)
.map(Car::getInsurance)
.map(Insurance::getName)
.orElse("-1");
}
//flatMap不会把结果包装成Optional,map会。
//原始写法判断
public static String getInsuranceNameByCheckPerson(Person person) {
if(null != person) {
if(null != person.getCar()) {
Car car = person.getCar();
if (null != car) {
Insurance insurance = car.getInsurance();
if (null != insurance) {
return insurance.getName();
}
}
}
}
return "UNKNOWN";
}
public static String getInsuranceNameByPerson(Person person){
return person.getCar().getInsurance().getName();
}
}