Optional API
一、Optional创建方式
前置条件:
Insurance对象:
public class Insurance {
private String name;
public String getName() { return name; }
}
1、empty
特点:使用get()方法时会抛出异常:No value present
范例:
Optional<Insurance> emptyOptional = Optional.<Insurance>empty();
使用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
特点:使用get(),不会抛异常
范例:
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
不管那种方式创建,都适用这几个方法。
1、orElseGet
说明:不为null就返回值,为null返回一个构造的对象supplier
范例:
Insurance orElseGetInsurance = ofNullableOptionalNull.orElseGet(Insurance::new);
System.out.println(orElseGetInsurance);
2、orElse
说明:不为null就返回值,否则返回一个引用
范例:
Insurance orElseInsurance = ofNullableOptionalNull.orElse(new Insurance());
System.out.println(orElseInsurance);
3、orElseThrow
说明:不为null就返回值,否则返回一个异常对象
范例:
Insurance orElseThrowInsurance = ofNullableOptionalNull.orElseThrow(RuntimeException::new);
输出结果:抛出运行时异常
Exception in thread "main" java.lang.RuntimeException
at java.base/java.util.Optional.orElseThrow(Optional.java:408)
4、orElseThrow
说明:不为null就返回值,否则返回一个自定义异常对象
范例:
ofNullableOptionalNull.orElseThrow(() -> new RuntimeException("yanxizhu Exception"));
输出结果:抛出自定义异常
Exception in thread "main" java.lang.RuntimeException: yanxizhu Exception
三、filter
先判断传入predicate是否null,让然后判断predicate传入字段是否存在,
不存在:返回this。
存在:判断predicate条件是否成立,成立:返回this,不成立:返回空。
源码:
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()源码:判断传入T是否为null
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
范例:
使用前创建Optional对象:
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(),都会报错:No value present: 因为name字段不存在
使用demo2:
范例1:
Optional<Insurance> insurance = ofInsurance.filter(t -> t.getName() == null);
insurance.get();
结果:
//不报错,因为name字段存在,且满足name==null
范例2:
Optional<Insurance> insurance = ofInsurance.filter(t -> t.getName() != null);
insurance.get();
结果:
//报错,因为name虽然存在,但是name!=null,不成立,会返回empty空,使用get()时就会抛出异常:No value present
使用demo3:
Optional<Insurance> insurance = ofNullableOptionalNull.filter(t -> t.getName() != null);
Optional<Insurance> insurance = ofNullableOptionalNull.filter(t -> t.getName() == null);
insurance.get();
结果:
//都报错:ofNullableOptional,会走empty创建的Optional,字段不存在,直接get获取值为空,报错:No value present
使用demo4:
范例1:
Optional<Insurance> insurance = ofNullableOptionalNotNull.filter(t -> t.getName() == null);
insurance.get();
结果:
//不会报错,走of方法创建的Optional,name字段存在,且name==null,所以不报错
范例2:
Optional<Insurance> insurance = ofNullableOptionalNotNull.filter(t -> t.getName() != null);
insurance.get();
结果:
//报错,因为虽然name存在,但是name!=null不成立,返回empty,get()就报错了
filter,总结:使用时不确定是否为empty,所以直接使用ofNullableOptional创建Optional.
四、map
使用任何方式创建的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;
}
使用:
//创建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、获取值之前判断值是否为空
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();
}
}
评论 (0)