java8-Optional使用Demo

 

/**
 * 在域模型中使用 Optional ,以及为什么它们无法序列化?
 * 我们展示了如何在你的域模型中使用 Optional ,将允许缺失或者暂
 * 无定义的变量值用特殊的形式标记出来。然而, Optional 类设计者的初衷并非如此,他们构
 * 思时怀揣的是另一个用例。这一点,Java语言的架构师Brian Goetz曾经非常明确地陈述过,
 * Optional 的设计初衷仅仅是要支持能返回 Optional 对象的语法。
 * 由于 Optional 类设计时就没特别考虑将其作为类的字段使用,所以它也并未实现
 * Serializable 接口。由于这个原因,如果你的应用使用了某些要求序列化的库或者框架,在
 * 域模型中使用 Optional ,有可能引发应用程序故障。然而,我们相信,通过前面的介绍,你
 * 已经看到用 Optional 声明域模型中的某些类型是个不错的主意,尤其是你需要遍历有可能全
 * 部或部分为空,或者可能不存在的对象时。如果你一定要实现序列化的域模型,作为替代方案,
 * 我们建议你像下面这个例子那样,提供一个能访问声明为 Optional 、变量值可能缺失的接口,
 * 代码清单如下:
 * public class Person {
 *  private Car car;
 *  public Optional<Car> getCarAsOptional() {
 *      return Optional.ofNullable(car);
 *  }
 * }
 **/
class Person {
    private Optional<Car> car;

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

    public Person(Optional<Car> car) {
        this.car = car;
    }
}

class Car {
    private Optional<Insurance> insurance;

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

    public Car(Optional<Insurance> insurance) {
        this.insurance = insurance;
    }
}

class Insurance {
    public Insurance(String name) {
        this.name = name;
    }

    private String name;

    public String getName() {
        return name;
    }
}

public class OptionalTest {
    private Person person;
    private Car car;
    private Insurance insurance;

    @Before
    public void initial() {
        insurance = new Insurance("insurance");
        car = new Car(Optional.of(insurance));
        person = new Person(Optional.of(car));
    }

    @Test
    public void refactor() {
        /*java8以前写法
        String name = null;
        if(insurance != null){
            name = insurance.getName();
        }
        */
        Optional<Insurance> optionalInsurance = Optional.ofNullable(insurance);
        Optional<String> res = optionalInsurance.map(Insurance::getName);
        System.out.println(res);
        /*java8以前这样写可能空指针异常,可以采用防御式
        public String getCarInsuranceName(Person person) {
            return person.getCar().getInsurance().getName();
        }
        */
        /*
        * 我们从以 Optional 封装的 Person 入手,对其调用 flatMap(Person::getCar) 。如
        * 前所述,这种调用逻辑上可以划分为两步。第一步,某个 Function 作为参数,被传递给由
        * Optional 封装的 Person 对象,对其进行转换。这个场景中, Function 的具体表现是一个方法
        * 引用,即对 Person 对象的 getCar 方法进行调用。由于该方法返回一个 Optional<Car> 类型的
        * 对象, Optional 内的 Person 也被转换成了这种对象的实例,结果就是一个两层的 Optional 对
        * 象,最终它们会被 flagMap 操作合并。从纯理论的角度而言,你可以将这种合并操作简单地看成
        * 把两个 Optional 对象结合在一起,如果其中有一个对象为空,就构成一个空的 Optional 对象。
        * 如果你对一个空的 Optional 对象调用 flatMap ,实际情况又会如何呢?结果不会发生任何改变,
        * 返回值也是个空的 Optional 对象。与此相反,如果 Optional 封装了一个 Person 对象,传递给
        * flapMap 的 Function ,就会应用到 Person 上对其进行处理。这个例子中,由于 Function 的返
        * 回值已经是一个 Optional 对象, flapMap 方法就直接将其返回。
        * 第二步与第一步大同小异,它会将 Optional<Car> 转换为 Optional<Insurance> 。第三步
        * 则会将 Optional<Insurance> 转化为 Optional<String> 对象,由于 Insurance.getName()
        * 方法的返回类型为 String ,这里就不再需要进行 flapMap 操作了。
        */
        Optional<Person> optPerson = Optional.of(person);
        String name = optPerson.flatMap(Person::getCar) //流的扁平化
                .flatMap(Car::getInsurance) //流的扁平化,将流最终转化化一个流
                .map(Insurance::getName) //映射流中的一项
                .orElse("unknow");//如果值为空所采用的默认值
        System.out.println(name);

    }

    @Test
    public void optional() {
        Optional<Car> optCar = Optional.empty();
        Optional<Car> optionalCar = Optional.of(car);
        System.out.println(optionalCar.get());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值