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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,113评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,644评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,340评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,449评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,445评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,166评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,442评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,105评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,601评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,066评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,161评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,792评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,351评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,352评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,584评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,618评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,916评论 2 344

推荐阅读更多精彩内容