JAVA8-Optional

如何为缺失的值建模

原始的两种方式:
在这里插入图片描述
在这里插入图片描述
Java8中引入了Optional类。java.util.Optional。
在这里插入图片描述
变量存在时,Optional类只是对类简单封装。变量不存在时,缺失的值会被建模成一个“空” 的Optional对象,由方法Optional.empty()返回。
Optional.empty()方法是一个静态工厂方法,它返回Optional类的特定单一实例。null和Optional.empty()没啥区别,就是防止出发nullException。
在这里插入图片描述
代码中person引用的是Optional, 而car引用的是Optional,这种方式非常清 地表达了你的模型中一个person 可能 有也可能没有car的情形,同样,car可能进行了保险,也可能没有保险。

使用Optional

  1. 声明一个空的Optional
    Optional<Car> optCar = Optional.empty();
  2. 根据一个非空值创建Optional
    Optional<Car> optCar = Optional.of(car);
    如果car是一个null,这段代码会立即抛出一个NullPointerException,而不是等到你试图访问car的属性值时才返回一个错误。
  3. 可接收null的Optional
    Optional<Car> optCar = Optional.ofNullable(car);如果car是null,那么得到的Optional对象就是个空对象。
使用map从Optional对象中提取和转换值

map操作会将提供的函数应用于流的每个元素。Optional对象可以看成特殊的集合数据,它至多包含一个元素。如果Optional包含一个值,那函数就将该值作为参数传递给map,对该值进行转换。如果Optional为空,那么什么也不做。
在这里插入图片描述

使用flatMap链接optional对象

看看下图代码如何应用Optional
在这里插入图片描述
我们可能会使用刚才提到的map方法

Optional<Person> optPerson = Optional.of(person);
    Optional<String> name =
        optPerson.map(Person::getCar)
                 .map(Car::getInsurance)
                 .map(Insurance::getName);

不幸的是,这段代码通过不了。getCar方法返回的是Optional<Car>类型。Car::getInsurance方法就无法执行了。因为Optional<Car>没有getInsurance方法。
这是就要用到flatMap函数,该方法接收一个函数作为参数,这个函数的返回值是另一个流。这个方法会应用到流中的每一个元素,最终形成一个新的流的流。但是flagMap会用流的内容替换每个新生成的流。换句话说,由方法生成的各个流会被合并或者扁平化为一个单一的流。
在这里插入图片描述
传递给optional的flatMap方法的函 数会将原始包含正方形的optional对象转换为包含三角形的optional对象。如果将该方法传递 给map方法,结果会是一个Optional对象,而这个Optional对象中包含了三角形;但flatMap 方法会将这种两层的Optional对象转换为包含三角形的单一Optional对象。
在这里插入图片描述
在这里插入图片描述
至目前为止,返回的Optional可能是两种情况:如果调用链上的任何一个方法返回一个 空的Optional,那么结果就为空,否则返回的值就是你期望的保险公司的名称。
如果一定要实现序列化域模型可以如下图这样
在这里插入图片描述

让我们看看Optional内部的方法

get()是这些方法中最简单但又最不安全的方法。如果变量存在,它直接返回封装的变量值,否则就抛出一个NoSuchElementException异常。
orElse(T other)它允许你在Optional对象不包含值时提供一个默认值。
orElseGet(Supplier<? extends T> other)是orElse方法的延迟调用版,Supplier 方法只有在Optional对象不含值时才执行调用。
orElseThrow(Supplier<? extends X> exceptionSupplier)和get方法非常类似, 它们 遇Optional对象为空时都会 出一个异常,但是使用orElseThrow你可以定制希 望 出的异常类型。
ifPresent(Consumer<? super T>)让你能在变量值存在时执行一个作为参数传入的 方法,否则就不进行任何操作。
empty返回一个空的 Optional 实例
filter如果值存在并且满足提供的谓词,就返回包含该值的 Optional 对象;否则返回一个空的 Optional 对象
of将指定值用 Optional 装之后返回,如果该值为 null,则 出一个 NullPointerException 异常
get如果该值存在,将该值用 Optional 装返回,否则 出一个 NoSuchElementException 异常

public Optional<Insurance> nullSafeFindCheapestInsurance(
Optional<Person> person, Optional<Car> car) {
        if (person.isPresent() && car.isPresent()) {
        }
        return;
}

如果还是这样判断那么和判null没什么区别。可以看下图这样。
在这里插入图片描述
用filter剔除特定值

Optional<Insurance> optInsurance = ...;
optInsurance.filter(insurance ->
                        "CambridgeInsurance".equals(insurance.getName()))
            .ifPresent(x -> System.out.println("ok"));

filter方法接受一个谓词作为参数。如果Optional对象的值存在,并且它符合谓词的条件, filter方法就返回其值;否则它就返回一个空的Optional对象。如果你还记得我们可以将 Optional看成最多包含一个元素的Stream对象,这个方法的行为就非常清 了。如果Optional对象为空,它不做任何操作,反之,它就对Optional对象中包含的值 加谓词操作。如果该操作的结果为true,它不做任何改变,直接返回该Optional对象,否则就将该值过 ,将 Optional的值空。

常规使用
Optional<Object> value = Optional.ofNullable(map.get("key"));

public static Optional<Integer> stringToInt(String s) {
try { 
        return Optional.of(Integer.parseInt(s));
    } catch (NumberFormatException e) {
        return Optional.empty();
    }
}
public int readDuration(Properties props, String name) {
        return Optional.ofNullable(props.getProperty(name))
.flatMap(OptionalUtility::stringToInt)
.filter(i -> i > 0)
.orElse(0);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值