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();
    }
}