Optional 的使用

一.简介

Optional 是一个对象容器,具有以下两个特点:

提示用户要注意该对象有可能为null

简化if else代码

二. 方法介绍

  1. 创建:

    Optional.empty(): 创建一个空的 Optional 实例

    Optional.of(T t):创建一个 Optional 实例,当 t为null时抛出异常

    Optional.ofNullable(T t):创建一个 Optional 实例,但当 t为null时不会抛出异常,而是返回一个空的实例

  2. 获取:

    get():获取optional实例中的对象,当optional 容器为空时报错

  3. 判断:

    isPresent():判断optional是否为空,如果空则返回false,否则返回true

    ifPresent(Consumer c):如果optional不为空,则将optional中的对象传给Comsumer函数

    orElse(T other):如果optional不为空,则返回optional中的对象;如果为null,则返回 other 这个默认值

    orElseGet(Supplier other):如果optional不为空,则返回optional中的对象;如果为null,则使用Supplier函数生成默认值other

    orElseThrow(Supplier exception):如果optional不为空,则返回optional中的对象;如果为null,则抛出Supplier函数生成的异常

  4. 过滤:

    filter(Predicate p):如果optional不为空,则执行断言函数p,如果p的结果为true,则返回原本的optional,否则返回空的optional

  5. 映射:

    map(Function<T, U> mapper):如果optional不为空,则将optional中的对象 t 映射成另外一个对象 u,并将 u 存放到一个新的optional容器中。

    flatMap(Function< T,Optional> mapper):跟上面一样,在optional不为空的情况下,将对象t映射成另外一个optional

    区别:map会自动将u放到optional中,而flatMap则需要手动给u创建一个optional

三 .demo使用

package com.dume.boot.code;


import java.util.Optional;
/**
 * @author dume
 * @create 2021-09-13 10:53
 *
 *  Optional是为了解决空指针异常,本质是一个包含可选值的包装类,或者说是一个容器
 **/


public class OptionalDemo {
    public static void main(String[] args) {
        Student studentnull = null;
        Student student = new Student("john1",11);
        Student student2 = new Student("john2",22);
        Student student3 = new Student("john3",33);
        Student student4 = new Student("john4",44);

        //isPresent判断值不为空,get返回对象
        System.out.println("*******************isPresent判断值不为空,get返回对象**********************");
        Optional<Student> optional = Optional.ofNullable(student);
        if(optional.isPresent()){
            Student back1 = optional.get();
            System.out.println("back1:"+back1.toString());
        }
        System.out.println("*********************ifPresent判断不为空, 并执行Lambda 表达式********************");
        //ifPresent判断不为空,Consumer(消费者) 参数,如果对象不是空的,就执行传入的 Lambda 表达式
        //注意没有返回值
        optional.ifPresent(u->ifFuction(u));

        System.out.println("*********************orElse判断不为空,否则返回默认值********************");
        //orElse判断不为空,否则返回默认值
        Student back2 =  Optional.ofNullable(studentnull).orElse(student2);
        System.out.println("back2:"+back2.toString());

        System.out.println("*******************orElseGet不为空时返回值;为空时作为参数传入函数式接口,并返回执行后的参数**********************");
        //orElseGet不为空时返回值;为空时,他会作为参数传入Supplier(供应者) 函数式接口,并返回执行后的参数
        Student back3 = Optional.ofNullable(studentnull).orElse(createStudent());
        Student back4 = Optional.ofNullable(studentnull).orElseGet(()->createStudent());
        System.out.println("back3:"+back3.toString());
        System.out.println("back4:"+back4.toString());
        /**
         * 可见当都为空时,orElse与orElseGet并无差别
         * 当都不为空时,orElse依然会执行,orElseGet不会执行。所以orElseGet效率更高
         */
        System.out.println("*********************当都不为空时,orElse依然会执行,orElseGet不会执行********************");
        Student back5 = Optional.ofNullable(student).orElse(createStudent());
        Student back6 = Optional.ofNullable(student).orElseGet(()->createStudent());
        System.out.println("back5:"+back5.toString());
        System.out.println("back6:"+back6.toString());

        //orElseThrow当为空时,抛出自定义异常
        System.out.println("*********************orElseThrow当为空时,抛出自定义异常********************");
        try {
            Student back7 = Optional.ofNullable(studentnull).orElseThrow(()-> new IllegalArgumentException());
        }catch (Exception e){
            e.printStackTrace();
        }

        //map转换值,map() 对值调用作为参数的函数,然后将返回的值包装在 Optional
        System.out.println("*********************map转换值********************");
        String back8 = Optional.ofNullable(studentnull).map(u->u.getName()).orElse("DEFUAFT");
        String back9 = Optional.ofNullable(studentnull).map(Student::getName).orElse("DEFUAFT");
        System.out.println("back8:"+back8);
        System.out.println("back9:"+back9);

        //flatMap() 也需要函数作为参数,并对值调用这个函数,然后直接返回结果;其实就是需要传入Optional类型参数,并返回Optional类型
        System.out.println("********************flatMap()转换值 需要传入Optional类型*********************");
        student.setPosition("Position");
        String position = Optional.ofNullable(student)
                .flatMap(u -> u.getPosition()).orElse("defaultPosition");
        System.out.println("back10:"+position);

        //filter() 接受一个 Predicate 参数,返回测试结果为 true 的值。
        // 如果测试结果为 false,会返回一个空的 Optional。
        System.out.println("*******************filter() 接受判断表达式,返回判断结果**********************");
        Optional<Student> optional11 = Optional.ofNullable(student).filter(u->u.getName()!=null&&u.getName().contains("1"));
        System.out.println("back11:"+optional11.isPresent());

        //使用Optional避免空指针来取值
        System.out.println("*******************使用Optional避免空指针来取值**********************");
        String code = Optional.ofNullable(new User())
                .flatMap(User::getAddress)
                .flatMap(Address::getCountry)
                .map(Country::getCode)
                .orElse("defaultcode");
        System.out.println("back12:"+code);
        System.out.println("*****************************************");
    }





    public static Student createStudent(){
        System.out.println("CreateStudent loading......");
        return new Student("Createjohn",0);
    }
    public static  void  ifFuction(Student student){
        System.out.println("ifFuction loading......");

    }

    static  class Student{
        public  String name;
        public  int age;
        public  String position;

        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", position=" + position +
                    '}';
        }

        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public void setPosition(String position) {
            this.position = position;
        }

        public Optional<String> getPosition() {
            return Optional.ofNullable(position);
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }


    }

    static  class User{
        Address address;


        public Optional<Address> getAddress() {
            return Optional.ofNullable(address);
        }

    }
    static  class Address{
        Country country;
        public Optional<Country> getCountry() {
            return Optional.ofNullable(country);
        }

    }
    static class Country{
        String code;

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }
    }




}


*******************isPresent判断值不为空,get返回对象**********************
back1:Student{name='john1', age=11, position=null}
*********************ifPresent判断不为空, 并执行Lambda 表达式********************
ifFuction loading......
*********************orElse判断不为空,否则返回默认值********************
back2:Student{name='john2', age=22, position=null}
*******************orElseGet不为空时返回值;为空时作为参数传入函数式接口,并返回执行后的参数**********************
CreateStudent loading......
CreateStudent loading......
back3:Student{name='Createjohn', age=0, position=null}
back4:Student{name='Createjohn', age=0, position=null}
*********************当都不为空时,orElse依然会执行,orElseGet不会执行********************
CreateStudent loading......
back5:Student{name='john1', age=11, position=null}
back6:Student{name='john1', age=11, position=null}
*********************orElseThrow当为空时,抛出自定义异常********************
java.lang.IllegalArgumentException
	at com.dume.boot.code.OptionalDemo.lambda$main$3(OptionalDemo.java:58)
	at java.util.Optional.orElseThrow(Optional.java:290)
	at com.dume.boot.code.OptionalDemo.main(OptionalDemo.java:58)
*********************map转换值********************
back8:DEFUAFT
back9:DEFUAFT
********************flatMap()转换值 需要传入Optional类型*********************
back10:Position
*******************filter() 接受判断表达式,返回判断结果**********************
back11:true
*******************使用Optional避免空指针来取值**********************
back12:defaultcode
*****************************************
Disconnected from the target VM, address: '127.0.0.1:60721', transport: 'socket'

Process finished with exit code 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值