Optional

Optional类入门

java.util.Optional<T>是java8中引入的一个新类,这是一个封装了Optional值的类。

变量存在时,Optional类只是对类简单封装。变量不存在时,缺失的值会被建模成一个“空”的Optional对象,由方法Optional.empty()返回。

Optional.empty()方法是一个静态工厂方法,它返回Optional类的特定单一实例。

Optional与传统代码的区别
//传统代码
public GroupParams  verifyGroupID(Long groupID){
    if (CommonUtils.isNull(groupID)){
        return null;
    }
    //根据groupID查询集团会员参数信息
    GroupParams groupParams = groupParamsMapper.queryByGroupID(groupID);
    if(CommonUtils.isNull(groupParams)){
        return null;
    }
    return groupParams;
}
 
//引入Optional(加入了自定义异常机制,可以抛出异常之后,由异常捕获机制直接讲错误码告知端,无需在方法层面多次判断)
public GroupParams verifyGroupID(Long groupID) {
 
    try{
       return of(groupID)
                .map(gID -> groupParamsMapper.queryByGroupID(gID))
                .orElseThrow(() -> new BusinessException(ErrorCode.GROUP_ID_NOT_EXISTS));
    }catch (NullPointerException e){
        throw new BusinessException(ErrorCode.EMPTY_GROUP_ID);
    }
}

应用Optional的几种模式

创建Optional对象

声明一个空的Optional

通过静态工厂方法Optional.empty,创建一个空的Optional对象:

声明一个空的Optional
Optional<CardInfo> optCard = Optional.empty();

依据一个非空值创建Optional

使用静态工厂方法Optional.of,依据一个非空值创建一个Optional对象:

如果cardInfo是一个null,这段代码会立即跑出一个NullPointerException,而不是等到试图访问cardInfo的属性值时才返回一个错误。

依据一个非空值创建Optional
Optional<CardInfo> optCard = Optional.of(cardInfo);

可接受null的Optional

使用静态方法Optional.ofNullable,可以创建一个允许null值的Optional对象:

可接受null的Optional
Optional<CardInfo> optCard = Optional.ofNullable(cardInfo);

使用map从Optional对象中提取值和转换值

Optional提供了一个map方法,可以从Optional中获取对象中的某些属性值,map方法接收一个Function对象

使用map从Optional对象中提取值
//声明一个Optional<CardInfo>对象,从中获取cardNO的值,无论cardinfo是否为null,下面代码都不会抛出异常
Optional<CardInfo> optCard = Optional.ofNullable(cardInfo);
Optional<String> optCardNO = optCard.map(CardInfo::getCardNO);

 

使用flatMap链接Optional对象

再使用流的时候,flatMap方法接受一个函数作为参数,这个函数的返回值是另一个流。这个方法会应用到流中的每一个元素,最终形成一个新的流的流。

但是flatMap会用流的内容替换每个新生成的流。换句话说,由方法生成的各个流会被合并或者或者扁平化为一个单一的流。

当需要链接多个Optional对象时,使用flatMap可以将多个Optional对象转换为单一的Optional对象。

使用flatMap链接Optional对象
//组合多个Optional对象,并返回一个包装cardTypeID的Optional对象
private Optional<Long> getCardTypeId(Optional<Long> groupIDOptional, Optional<Long> shopIDOptional){
 
    return groupIDOptional.flatMap(gID -> shopIDOptional.filter(sID -> sID > 0).map(sID -> cardTypeShopMapper.selectByGroupIDAndShopID(gID,sID))).map(s -> s.getCardTypeID());
}

默认行为及解引用Optional对象

Optional类提供了多种方法获取Optional实例中的变量值。

  • get()
  • orEles(T other)
  • orElseGet(Supplier<? extends T> other)  是orElse的延迟调用版
  • orElseThrow(Supplier<? extends X> exceptionSupplier)
  • ifPresent(Consumer<? super T>)

使用filter剔除特定的值

filter方法接受一个谓词作为参数。如果Optional对象的值存在,并且它符合谓词的条件,filter方法就返回其值;否则它就返回一个空的Optional对象。

使用filter剔除特定的值
//通过filter过滤状态值大于0  并且不与当前传递的状态值相等的状态
public Optional<Integer> canUpdateCardStatus(Integer optionType,Integer cardStatus){
        try{
           return  of(optionType)
                   .flatMap(o -> of(cardStatus).map(s -> CardLogTypeEnum.getCardLogTypeEnum(o).getStatusAfterChange()))
                   .filter( i -> i > 0 && i != cardStatus);
       }catch (NullPointerException e){
              throw new BusinessException(ErrorCode.EMPTY_UPDATE_CARD_STATUS_PARAM);
       }
    }

Optional类的方法

方法
描述
empty

返回一个空的Optional实例

filter 如果值存在并且满足提供的谓词,就返回包含该值的Optional对象;否则返回一个空的Optional对象
flatMap 如果值存在,就对该值执行提供的mapping函数调用,返回一个Optional类型的值,否则就返回一个空的Optional对象
get 如果该值存在,将该值用Option封装返回,否则跑出一个NoSuchelementException异常
ifPresent 如果值存在,就执行使用该值的方法调用,否则什么都不做
isPresent 如果值存在就返回true,否则则返回false
map 如果值存在,就对该值执行提供的mapping函数调用
of 将指定值用Optional封装之后返回,如果该值为null,则抛出一个NullPointerException异常
ofNullable

将指定值用Optional封装之后返回,如果该值为null,则返回一个空的Optional对象

orElse

如果有值则将其返回,否则返回一个由指定的Supplier接口生成的值
orElseThrow 如果有值则将其返回,否则抛出一个由指定的Supplier接口生成的异常

 

注意:

  1. Optional的设计初衷仅仅是要支持能返回Optional对象的语法。由于Optional类设计时就没特别考虑将其作为类的字段使用,所以它也并未实现Serializable接口。由于这个原因,如果你的应用使用了某些要求序列化的库或者框架,在域模型中使用Optional,有可能引发程序故障。
  2. Optional也提供了基本数据类型的Optional对象,比如OptionalInt,OptionalLong,OptionalDouble,但是由于它们不支持map,flatMap,filter方法,而这些方法是Optional对象中最有用的方法。基础类型的Optional对象不能组合使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值