入门jdk1.8处理空指针API-Optional

入门jdk1.8处理空指针API-Optional

类图结构

在这里插入图片描述

简要说明

/**
 * A container object which may or may not contain a non-null value.
 * If a value is present, {@code isPresent()} will return {@code true} and
 * {@code get()} will return the value.
 *
 * <p>Additional methods that depend on the presence or absence of a contained
 * value are provided, such as {@link #orElse(java.lang.Object) orElse()}
 * (return a default value if value not present) and
 * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block
 * of code if the value is present).
 *
 * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
 * class; use of identity-sensitive operations (including reference equality
 * ({@code ==}), identity hash code, or synchronization) on instances of
 * {@code Optional} may have unpredictable results and should be avoided.
 *
 * @since 1.8
 */

一个可以包含非空值也可以不包含非空值的容器对象。如果一个值存在,isPresent()将返回true和get()将返回值。
构造方法

    /**
     * 空的Optional
     */
    private static final Optional<?> EMPTY = new Optional<>();

    /**
     * If non-null, the value; if null, indicates no value is present
     */
    private final T value;

    /**
     * Constructs an empty instance.
     *
     * @implNote Generally only one empty instance, {@link Optional#EMPTY},
     * should exist per VM.
     */
    private Optional() {
        this.value = null;
    }

常用api

构建空的Optional实例对象

    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

构建指定类型的Optional

    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

构建非空的对象

    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }

构建各种对象,对空对象做了处理

    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

获取对应数值对象情况

    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

如果具体数值存在,返回true,否则false

    /**
     * Return {@code true} if there is a value present, otherwise {@code false}.
     *
     * @return {@code true} if there is a value present, otherwise {@code false}
     */
    public boolean isPresent() {
        return value != null;
    }

如果Optional存在实例对象,进行逻辑操作,通过Consumer处理

    /**
     * If a value is present, invoke the specified consumer with the value,
     * otherwise do nothing.
     *
     * @param consumer block to be executed if a value is present
     * @throws NullPointerException if value is present and {@code consumer} is
     * null
     */
    public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
    }

过滤操作,筛选数据,前提是不能为空

    public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
    }

实践操作

        // 创建空的Optional,内部通过构造方法new一个Optional
        Optional<Object> empty = Optional.empty();

        // 根据非空对象创建Optional,如果对象为空,抛异常空指针
        User user = User.builder().userName("小米粒").age(10).build();
        Optional<User> userOptional = Optional.of(user);
        log.info("userOptional : [{}]" , userOptional);
        // userOptional : [Optional[NoDaoTest.User(userName=小米粒, age=10, loginTime=null, account=null)]]

        // 可以接收对象为空
        User nullUser=null;
        Optional<User> nullUserOptional = Optional.ofNullable(nullUser);
        log.info("nullUserOptional : [{}]" , nullUserOptional);
        // nullUserOptional : [Optional.empty]

        // 判断Optional是否包含对象
        boolean userOptionalPresent = nullUserOptional.isPresent();
        log.info("userOptionalPresent : [{}]" , userOptionalPresent);
        // userOptionalPresent : [false]
        boolean userOptionalPresent1 = userOptional.isPresent();
        log.info("userOptionalPresent1 : [{}]" , userOptionalPresent1);
        //  userOptionalPresent1 : [true]

        // 如果Optional包含属性value-》业务数据,可以做一些特殊处理
        userOptional.ifPresent(item->item.setAge(88));
        log.info("如果Optional包含属性value-》业务数据,可以做一些特殊处理 userOptional : [{}]" , userOptional);
        // 如果Optional包含属性value-》业务数据,可以做一些特殊处理 userOptional : [Optional[NoDaoTest.User(userName=小米粒, age=88, loginTime=null, account=null)]]

        // 获取容器中属性,类似于getter方法
        User userTarget = userOptional.get();
        log.info("userTarget : [{}]" , userTarget);
        // userTarget : [NoDaoTest.User(userName=小米粒, age=88, loginTime=null, account=null)]

        // 如果Optional中属性为空,可以创建新的对象返回,不为空正常返回
        User userOrElse = nullUserOptional.orElse(User.builder().userName("笑一笑").build());
        log.info("userOrElse : [{}]" , userOrElse);
        // userOrElse : [NoDaoTest.User(userName=笑一笑, age=null, loginTime=null, account=null)]

        // 如果Optional属性为空,通过Supplier函数创建对象返回,否则返回原始对象
        User userOrElseGet = nullUserOptional.orElseGet(() -> User.builder().userName("唠一唠").build());
        log.info("userOrElseGet : [{}]" , userOrElseGet);
        // userOrElseGet : [NoDaoTest.User(userName=唠一唠, age=null, loginTime=null, account=null)]

        // 如果Optional属性为空,抛出指定异常
        // User userOrElseThrow = nullUserOptional.orElseThrow(() -> new IllegalArgumentException("指定异常抛出信息"));
        // log.info("userOrElseThrow : [{}]" , userOrElseThrow);

        // 过滤操作
        User userFilter = User.builder().userName("过滤名称").build();
        Optional.ofNullable(userFilter)
                .filter(item->StringUtils.equals("过滤名称", item.getUserName()))
                .ifPresent(x->log.info("x : [{}]" , x)
                );
        //  x : [NoDaoTest.User(userName=过滤名称, age=null, loginTime=null, account=null)]

        User userMap = User.builder().userName("map").build();
        Optional.ofNullable(userMap)
                .map(item->{
                    item.setAge(10);
                    return item;
                });
        log.info("userMap : [{}]" , userMap);
        // userMap : [NoDaoTest.User(userName=map, age=10, loginTime=null, account=null)]
        
        

应用场景

场景一: 对象不为空,做一些逻辑处理

// 以前开发
if(userInfo != null){
    userInfo.setProperty("*");
}
// 现在开发
Optional.ofNullable(userMap)
        .ifPresent(item->item.setAge(99));
log.info("场景一:userMap  [{}]" , userMap);
// 场景一:userMap  [NoDaoTest.User(userName=map, age=99, loginTime=null, account=null)]

场景二:对象为空抛异常,或者对象某个字段为空抛指定异常

// 以前开发
if(userInfo != null){
    if(userInfo.getUserName() != null && userInfo.getUserName() != ""){
        // 逻辑处理
    }
}

// 现在开发
// 无论是user为空还是名字为空,抛异常
User userEmpty = User.builder().build();
User nullUser = null;
Optional.ofNullable(userEmpty)
        .filter(item -> StringUtils.isNotBlank(item.getUserName()))
        .orElseThrow(() -> new IllegalArgumentException("对象为空或者姓名为空"))
;

场景三:级联判空,父节点,子节点,子子属性

Student son = Student.builder().build();
User parentUser = User.builder()
        .userName("父节点名称")
        .student(son)
        .build();
Optional.ofNullable(parentUser)
        .map(User::getStudent)
        .map(Student::getStuName)
        .orElseThrow(()->new IllegalArgumentException("子节点不为空或者子节点用户信息不为空"));
     
Optional.ofNullable(parentUser)
   .map(User::getStudent)
   .map(Student::getStuName)
   .orElseThrow(()->new IllegalArgumentException("子节点不为空或者子节点用户信息不为空"));

在这里插入图片描述

场景四:属性为空,默认值赋值

 Optional.ofNullable(userMap)
         .filter(item -> StringUtils.isBlank(item.getUserName()))
         .map(item -> {
             item.setUserName("李华");
             return item;
         });
// 16:19:21.164 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - userMap : [NoDaoTest.User(userName=李华, age=99, loginTime=null, account=null, student=null)]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值