hi,你好!欢迎访问本站!登录
本站由网站地图腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

Java8系列 (五) Optional类

2019-11-18杂谈搜奇网27°c
A+ A-

概述

在Java8之前, 假如需要对一个变量做一次 null 搜检, 通常会像下面如许写

    T t = service1.query();
    if (t != null) {
        K k = service2.update(t);
        if (k != null) {
            U u = service3.save(k);
        }
    }

假如营业比较复杂, 可能会像上面那样, 运用 if 语句举行多层嵌套, 后期难以扩大。

在Java8中新引入了一个 Optional 类, Optional 类会对可能为 null 值的变量举行建模, 如许你就没必要直接将 null 赋值给变量, 也就没必要像上面那样举行多层嵌套搜检。

在正式引见 Optional 类的 API之前, 先引入一些实体类, 背面的代码示例会经常用到它们。

@Data
public class Person {

    private Car car;
    private int age;

    public Optional<Car> getCar() {
        return Optional.ofNullable(car);
    }
}

@Data
public class Car {

    private Insurance insurance;

    public Optional<Insurance> getInsurance() {
        return Optional.ofNullable(insurance);
    }
}

@Data
public class Insurance {

    private String name;
}
View Code

建立Optional对象

Optional 类供应了三种体式格局来建立 Optional 对象

  • empty(): 建立一个空的 Optional 对象
  • of(): 将指定值用 Optional 封装以后返回,假如该值为 null ,则抛出一个 NullPointerException 非常
  • ofNullable(): 将指定值用 Optional 封装以后返回,假如该值为 null ,则返回一个空的 Optional 对象
    @Test
    public void test1() {
        //声明一个空的optional
        Optional<Car> c1 = Optional.empty();
        //依据一个非空的值建立optional, 假如传入的值是null,会抛出空指针非常
        Optional<Car> c2 = Optional.of(new Car());
        //可接受null的Optional
        Optional<Object> c3 = Optional.ofNullable(null);
    }

flatMap和map用法

flatMap()和map()都是在指定值存在时, 就对该值实行供应的 mapping 函数挪用, 返回一个 Optional 范例的值, 不然就返回一个空的 Optional 对象。

注重 flatMap() 要领的转换函数是 Function<? super T, Optional<U>> mapper , 这个特征和前面引见的 Stream 类的 flatMap() 很像。

检察一下 Optional 类的源码, flatMap() 会将 Optional<T> 中的 T 转换成 Optional<U>, 再将转换后的 Optional<U> 直接作为要领返回值返回。

    @Test
    public void test2() {
        Optional<Person> person = Optional.ofNullable(new Person());
        String name = person.flatMap(Person::getCar).flatMap(Car::getInsurance).map(Insurance::getName).orElse("哪吒之魔童降世");
        System.out.println(name); //result: 哪吒之魔童降世
    }

上面的代码示例中,  因为 Person 实体类中 car 属性是一个 null 值, 所以  person.flatMap(Person::getCar) 这个操纵会获得一个空的Optional 对象。

如许就致使了背面的 flatMap() 和 map() 两次转换都返回一个空的 Optional 对象。orElse() 要领的寄义是假如有值则将其返回,不然返回一个默认值。所以末了的输出效果是默认值  哪吒之魔童降世 。

在现实营业中, 你能够像下面如许将 Optional 作为要领入参和返回值运用

    @Test
    public void test3() {
        Optional<Insurance> insurance1 = find(Optional.of(new Person()), Optional.empty());
        System.out.println(insurance1);//result: Optional.empty
        Optional<Insurance> insurance2 = find(Optional.of(new Person()), Optional.of(new Car()));
        System.out.println(insurance2);//result: Optional[Insurance(name=null)]
    }

    public Optional<Insurance> find(Optional<Person> person, Optional<Car> car) {
        return person.flatMap(p -> car.map(c -> find(p, c)));
    }

    private Insurance find(Person p, Car c) {
        return new Insurance();
    }

filter和ifPresent

  • filter(): 假如值存在而且满足供应的谓词, 就返回包括该值的 Optional 对象; 不然返回一个空的 Optional 对象
  • ifPresent(): 假如值存在, 就实行运用该值的要领挪用, 不然什么也不做
    @Test
    public void test4() {
        Optional.of("攀登者").filter(i -> i.length() < 4).ifPresent(System.out::println);//打印: 攀登者
        Optional.<String>empty().filter(i -> i.length() < 4).ifPresent(System.out::println);//没有输出
    }

下面是一个测试示例, 到当地去运转看下输出效果, 它能够帮你从新明白一下前面引见的几个 API 的用法。

    @Test
    public void test5() {
        System.out.println(getCarInsuranceName(Optional.empty(), 8));//result: 运气之夜
        Person p = new Person();
        p.setAge(10);
        System.out.println(getCarInsuranceName(Optional.of(p), 8));//result: 运气之夜
        Insurance insurance = new Insurance();
        insurance.setName("知否知否");
        Car car = new Car();
        car.setInsurance(insurance);
        p.setCar(car);
        System.out.println(getCarInsuranceName(Optional.of(p), 8));//result: 知否知否
    }

    //找出岁数大于或许即是 minAge 参数的 Person 所对应的保险公司列表。
    public String getCarInsuranceName(Optional<Person> person, int minAge) {
        return person.filter(p -> p.getAge() >= minAge).flatMap(Person::getCar).flatMap(Car::getInsurance).map(Insurance::getName).orElse("运气之夜");
    }

Optional与非常的对照

通常在因为某种要素下, 函数没法准确返回某个值, 罕见的做法就是运用 try/catch 语句处置惩罚返回一个null值, 或许不做任何处置惩罚直接抛出一个非常。

假如函数没法准确返回某个值, 且你不需要它抛出非常, 而是要它返回一个默认值, 那末 Optional 能够帮您更文雅的完成

    @Test
    public void test6() {
        String value = "test";
        Integer res = Optional.of(value).flatMap(this::str2Int).filter(i -> i > 0).orElse(0);
        System.out.println(res);//result: 0
    }

    private Optional<Integer> str2Int(String str) {
        try {
            //假如能准确剖析, 就将其封装在 Optional 中返回
            return Optional.of(Integer.valueOf(str));
        } catch (NumberFormatException ex) {
            //假如剖析发作非常, 就返回一个空的 Optional
            return Optional.empty();
        }
    }

上面的代码清单,   Integer.valueOf() 会在入参不是一个整型数值时, 抛出 NumberFormatException , 我们这里对它做了处置惩罚, 当剖析发作非常时, 就返回一个空的 Optional 对象。

上面的用例只要在 value 变量是大于零的整型数值时, 才会输出 value 变量的值, 不然, 输出效果都是默认值 0。

总结

末了, 来一张大图

参考资料

Java8 实战

作者:张小凡
出处:https://www.cnblogs.com/qingshanli/
本文版权归作者和博客园共有,迎接转载,但未经作者赞同必需保存此段声明,且在文章页面显著位置给出原文衔接,不然保存追查法律责任的权益。假如以为另有协助的话,能够点一下右下角的【引荐】。

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
Java8系列 (五) Optional类

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282218.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>