JAVA8-Optional API

admin
2022-09-15 / 0 评论 / 99 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年09月15日,已超过581天没有更新,若内容或图片失效,请留言反馈。

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

评论 (0)

取消