JDK8新特性之Optional(四)

JDK8新特性之Optional

Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException),Optional<T>类在java.util包下,是一个容器类,它可以保存类型T的值,代表这个值存在;或者仅仅保存null,表示这个值不存在。原来用null表示一个值不存在,现在Optional可以更好的表达这个概念,并且可以避免空指针异常。
Optional类的javadoc描述如下:这是一个可以为null的容器对象,如果值存在则ispresent()会返回true,调用get()方法会返回该对象。

Optional类方法介绍

先创建一个People类,在接下来的测试中会用到该类

public class People {
    private String name;
    private int age;
    private People friend;
public People() {
    }
public People(String name, int age, People friend) {
        this.name = name;
        this.age = age;
        this.friend = friend;
    }

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

    public People getFriend() {
        return friend;
    }

    public void setFriend(People friend) {
        this.friend = friend;
    }

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

创建Optional类对象的方法

  • Optional.of(T t):创建一个Optional实例,t必须非空
  • Optional.empty():创建一个空的Optional实例
  • Optional.ofNullable(T t):t可以为null
 @Test
    public void test01(){
        // Optional.of(T t):创建一个Optional实例,t必须非空
        People people = new People();
        people.setName("张三");
        people.setAge(18);
        // 如果这行代码放开运行会报NullPointerException错,因为people为Null
//        people = null;
        Optional<People> peopleOptional = Optional.of(people);
        System.out.println(peopleOptional);// 结果:Optional[People{name='张三', age=18, friend=null}]

    }

    @Test
    public void test02(){
        // Optional.ofNullable(T t):t可以为null
        People people = new People();
        people.setName("李四");
        people.setAge(22);
        // 如果people=null,则
//        people = null;
        Optional<People> peopleOptional = Optional.ofNullable(people);
        /**
         * people不为空时结果:Optional[People{name='李四', age=22, friend=null}]
         * people为空时的结果:Optional.empty
         */
        System.out.println(peopleOptional);
    }

    @Test
    public void test03(){
        // Optional.empty():创建一个空的Optional实例
        Optional emptyPeople = Optional.empty();
        System.out.println(emptyPeople);// 结果:Optional.empty
        /**
         * Optional.empty()相当于将以前的null 包装了一下
         * 以前是people == null
         * 我们结合Optional.ofNullable来使用一下
         */
        People people = null;
        Optional<People> peopleOptional = Optional.ofNullable(people);
        Optional<People> empty = Optional.empty();
        if(peopleOptional == empty){
            System.out.println("true");// 输出true
        }
    }

判断Optional容器是否包含对象

  • boolean isPresent():判断是否包含对象
  • void ifPresent(Consumer<? super T> consumer):如果有值,就执行consumer接口的实现代码,并且该值会作为参数传递给它
 @Test
    public void test04(){
        // boolean isPresent():判断是否包含对象
        People people = new People();
        people.setName("李四");
        people.setAge(22);
        Optional<People> peopleOptional1 = Optional.ofNullable(people);
        System.out.println(peopleOptional1.isPresent());// 结果:true

        people = null;
        Optional<People> peopleOptional2 = Optional.ofNullable(people);
        System.out.println(peopleOptional2.isPresent());// 结果:false

        // void ifPresent(Consumer<? super T> consumer):如果有值,就执行consumer接口的实现代码,并且该值会作为参数传递给它
        // 加入People存在则取输出它的朋友信息
        People people2 = new People("王五",23,new People("小明",21,null));
        Optional<People> optionalPeople2 = Optional.ofNullable(people2);
        optionalPeople2.ifPresent(p -> System.out.println(p.getFriend()));// 结果:People{name='小明', age=21, friend=null}

    }

获取Optional容器的对象

  • T get():如果调用对象包含值,返回该值,否则抛异常
  • T orElse(T other):如果有值则将其返回,否则返回指定的other对象
  • T orElseGet(Supplier<? extends T> other):如果有值则将其返回,否则返回由Supplier接口实现提供的对象
  • T orElseThrow(Supplier<? extends X> exceptionSupplier):如果有值则将其返回,否则抛出由Supplier接口实现提供的异常
 @Test
    public void test05(){
        // T get():如果调用对象包含值,返回该值,否则抛异常
        People people = new People("詹姆斯",36,null);
//        people = null;
        Optional<People> optionalPeople = Optional.ofNullable(people);
        // 当people为null时抛异常:java.util.NoSuchElementException: No value present
        People result = optionalPeople.get();
        System.out.println(result);// 结果是:People{name='詹姆斯', age=36, friend=null}
    }
    @Test
    public void test06(){
        People people = new People("詹姆斯",36,null);;
//        people = null;
        Optional<People> optionalPeople = Optional.ofNullable(people);
        // T orElse(T other):如果有值则将其返回,否则返回指定的other对象
        People result = optionalPeople.orElse(new People("韦德", 28, null));
        /**
         * people不为null时返回people:People{name='詹姆斯', age=36, friend=null}
         * 为null时返回自己设置的默认对象:People{name='韦德', age=28, friend=null}
         */
        System.out.println(result);

        // T orElseGet(Supplier<? extends T> other):如果有值则将其返回,否则返回由Supplier接口实现提供的对象
        People result2 = optionalPeople.orElseGet(() -> new People("保罗", 38, null));
        /**
         * people不为null时返回people:People{name='詹姆斯', age=36, friend=null}
         * 为null时返回自己设置的默认对象:People{name='保罗', age=38, friend=null}
         */
        System.out.println(result2);
    }

    @Test
    public void test07(){
        // T orElseThrow(Supplier<? extends X> exceptionSupplier):如果有值则将其返回,否则抛出由Supplier接口实现提供的异常
        // 这里其实和上面的orElseGet有点类似,只不过这里是返回异常对象
        // 这个主要是用于可以抛出指定异常
        People people = new People("詹姆斯",36,null);;
        people = null;
        Optional<People> optionalPeople = Optional.ofNullable(people);
        People result = optionalPeople.orElseThrow(() -> new RuntimeException("值不存在"));
        System.out.println(result);

    }

总结

Optional类主要的作用其实是为了消除空指针,虽然并不能完全消除但是给我们带来一些更方便的操作,比如为空时设置默认值,为空时抛出指定异常等。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容