还在用if判空?试试Optional吧!

我相信,每一个Java程序员都必然会遇到过这样一个异常:NullPointerException(NPE),空指针异常。这个异常让我们很痛疼,如果写的代码不够鲁棒,导致尝试访问空对象的方法或字段时就会抛出这个异常。

因此合格的程序员都会在使用对象前进行判空,常见的是用if条件判断,如果对象不为空则可以继续进行访问对象字段和方法的操作,如果对象为空那么不可以进行访问对象的字段和方法的操作。常用编程范式如下:

public void printUserName(User user) {
    if (user == null) {
        return;
    }
    System.out.println(user.getName());
}

大量的这种重复逻辑的代码显得十分不优雅~,于是在Java8中JDK很贴心地为我们提供了更优雅的处理方式:借助Optional类,帮助我们从if判空的桎梏中解脱出来。

熟悉Optional

1.1 通过一个demo了解Optional用法

如果不清楚API也不要紧,先大概了解一下用法,后面我会详细介绍API的

User user = new User("zhanghaobo");
    // 创建一个Optional对象,里面内容是user
    Optional<User> optional = Optional.ofNullable(user);
    optional.ifPresent(
        user1 -> {
          System.out.println("user对象非空!");
          System.out.println(user1.getUsername());
        }
    );

这段代码的输出是:

user对象非空!
zhanghaobo

使用了ifPresent这个函数,意思是如果optional这个对象里面不为空,才会执行lambda表达式的语句,否则就不执行。

这样看起来是不是很清爽了,根本不需要我们再去每次if判断了。十分优雅~

那接下来我们就看看Optional类相关的API吧

1.2 创建Optional对象

①使用静态方法 empty() 创建一个内容为空的Optional 对象

Optional<User> empty = Optional.empty();
System.out.println(empty);
// 输出:Optional.empty

②使用静态方法 of() 创建一个内容不为空的Optional 对象

User user = new User("zhanghaobo");
Optional<User> optional = Optional.of(user);
//输出:Optional[User{username='zhanghaobo'}]

③使用静态方法 ofNullable() 创建一个内容既可空又可非空的 Optional 对象

User notnull = new User("zhanghaobo");
    User isnull = null;
    Optional<User> notNullOptional = Optional.ofNullable(notnull);
    Optional<User> isnullOptional = Optional.ofNullable(isnull);
    System.out.println(notNullOptional); //输出:Optional[User{username='zhanghaobo'}]
    System.out.println(isnullOptional); //输出:Optional.empty

1.3 判断对象是否存在?

通过 isPresent()方法判断一个 Optional 对象内部的值是否存在,如果存在,则该方法返回 true,如果不存在,则返回 false。不用再写 user != null 这种判空了。

User user = new User("zhanghaobo");
    Optional<User> optional = Optional.ofNullable(user);
    System.out.println(optional.isPresent()); //true
    
    User nullUser = null;
    Optional<User> optionalNull = Optional.ofNullable(nullUser);
    System.out.println(optionalNull.isPresent()); //false

1.4 非空表达式

我们知道Java8中有很多新特性,其中包括函数式接口、lambda表达式、流式操作等,提供这些特性以支持函数式编程。

Optional类中的ifPresent()方法在optional对象里面的值不为空的情况下允许我们使用函数式编程的方式执行一些代码,而当optional对象里面的值为空时则不会执行,因此,我把它称为非空表达式。如果没有该方法的话,我们通常需要先通过 isPresent() 方法对 Optional 对象进行判空后再执行相应的代码,而现在我们可以这么写:

User user = new User("zhanghaobo");
    Optional<User> optional = Optional.ofNullable(user);
    optional.ifPresent(user2 -> {
      System.out.println("User对象非空,username is :" + user.getUsername());
    });

输出为:

User对象非空,username is :zhanghaobo

如果user是null的话,将不会执行ifPresent里面的lambda表达式。

tips:Java 9 后还可以通过方法 ifPresentOrElse(action, emptyAction) 执行两种结果,非空时执行 action,空时执行 emptyAction。

1.5 获取or设置默认值

有这样的一些场景,如果Optional对象里面的值为空,那么返回一个默认值。
这时候可以使用orElse方法。

User user = null;
    User realUser = Optional.ofNullable(user).orElse(new User("zhanghaobo"));
    System.out.println(realUser); //输出:User{username='zhanghaobo'}

    User user1 = new User("lisi");
    User realUser1 = Optional.ofNullable(user1).orElse(new User("zhanghaobo"));
    System.out.println(realUser1); //输出:User{username='lisi'}

从上面的demo可以看出:
orElse() 方法返回 Optional 对象中包含的值,如果该值不为 null,则返回;否则返回默认值。该方法的参数类型和值的类型一致。

orElseGet() 方法与 orElse() 方法类似,但参数类型不同。如果 Optional 对象中的值为 null,则执行参数中的函数。

User user = null;
    User realUser = Optional.ofNullable(user).orElseGet(() -> {
      return new User("zhanghaobo");
    });
    System.out.println(realUser); //输出:User{username='zhanghaobo'}

那orElse和orElseGet有什么区别呢?看如下代码:

User user = new User("zhanghaobo");
    User orElse = Optional.ofNullable(user).orElse(getDefaultUser());
    System.out.println("#############");
    User orElseGet = Optional.ofNullable(user).orElseGet(OptionalDemo::getDefaultUser);
  }
  
  public static User getDefaultUser() {
    System.out.println("invoke getDefaultUser method");
    return new User("lisi");
  }

输出为:

invoke getDefaultUser method
#############

证明orElseGet的参数不一定会被执行,所以性能会比orElse好。

1.6 值过滤--filter

对Optional对象中包含的值进行过滤,如果满足filter函数参数的lambda表达式中的条件,则返回此Optional对象,如果不满足条件,则返回Optional.empty。

User user = new User("zhanghaobo");
    Optional<User> optionalUser = Optional.ofNullable(user).filter(user1 -> {
      return user1.getUsername().equals("lisi");
    });
    System.out.println(optionalUser); //输出:Optional.empty

1.7 数据转换--map

使用map可以对Optional中包含的值进行一些转换操作。比如下面的demo,就是把user变成了一个新的user。

User user = new User("zhanghaobo");
Optional<User> optionalUser = Optional.ofNullable(user).map(user1 -> {
  return new User("lisi");
});
System.out.println(optionalUser); //输出:Optional[User{username='lisi'}]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java中,我们经常需要进行非判断来避免NullPointException异常的出现。在过去,我们通常会使用if语句来进行判断,但是随着Java 8版本的推出,Optional类和Stream类的引入可以更加简洁和可读地进行代码编写。 Optional类是一个容器对象,它可以容纳一个非对象或者不包含任何对象(称为“”)。在使用Optional类时,我们可以利用它提供的isPresent()方法来判断是否包含非对象,如果是,则可以直接通过get()方法获取该对象。例如: ``` String str = null; Optional<String> optionalStr = Optional.ofNullable(str); if (optionalStr.isPresent()) { System.out.println(optionalStr.get()); } ``` 上述代码可以改写为: ``` String str = null; Optional.ofNullable(str).ifPresent(System.out::println); ``` Stream类是Java 8版本中引入的一个新类,它提供了一套函数式编程的API,可以对集合数据进行流式处理。在使用Stream类时,我们可以使用filter方法进行非判断。例如: ``` List<String> list = Arrays.asList("a", "b", null, "d"); list.stream().filter(item -> item != null).forEach(System.out::println); ``` 上述代码可以改写为: ``` List<String> list = Arrays.asList("a", "b", null, "d"); list.stream().filter(Objects::nonNull).forEach(System.out::println); ``` 使用Optional类和Stream类可以更加简化和优化代码的逻辑,减少代码冗余,提高代码执行效率和可读性。但是,在实际使用时也需要注意,Optional类和Stream类的使用要适当,过度使用反而会导致代码可读性变差和效率降低。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叹了口丶气

觉得有收获就支持一下吧~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值