Optional的使用

Optional的使用

1、构造方式

Optional 的三种构造方式: Optional.of(obj), Optional.ofNullable(obj) 和 Optional.empty()

1.1、Optional.of(obj)

它要求传入的 obj 不能是 null 值的, 否则 NullPointerException.

使用场景:

\1. 当我们非常非常的明确将要传给 Optional.of(obj) 的 obj 参数不可能为 null 时;

\2. 当obj 为 null 立即报告 NullPointException 异常, 而不是隐藏空指针异常时.

1.2、Optional.ofNullable(obj)

传 null 进到就得到 Optional.empty(), 非 null 就调用 Optional.of(obj).

1.3、Optional.empty()

内部value是null

2、不推荐的使用方式

Optional user = ……

if (user.isPresent()) {

return user.getOrders();

} else {

return Collections.emptyList();

}

这种方式和我们直接使用obj != null做判断没什么区别。实际上,当我们还在以如下几种方式使用 Optional 时, 就说明你的使用方式可能有问题:

(1)调用 isPresent() 方法时或者调用 get() 方法时。这两种方法应该认为是private的,你最好不要直接使用。

(2)Optional 类型作为类/实例属性时。Optional 类型不可被序列化, 用作字段类型会出问题

(3)Optional 类型作为方法参数时。

3、正确的使用方式

Optional 中我们真正可依赖的应该是除了 isPresent() 和 get() 的其他方法:

public Optional map(Function<? super T, ? extends U> mapper)

public T orElse(T other)

public T orElseGet(Supplier<? extends T> other)

public void ifPresent(Consumer<? super T> consumer)

public Optional filter(Predicate<? super T> predicate)

public Optional flatMap(Function<? super T, Optional> mapper)

public T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X

3.1、存在则返回数据

3.1.1、orElse

存在即返回, 无则提供默认值

return user.orElse(null);

return user.orElse(UNKNOWN_USER);

3.1.2、orElseGet

存在即返回, 无则由函数来产生

return user.orElseGet(() -> fetchAUserFromDatabase());

3.1.3、orElseThrow

存在即返回, 无则抛出supplier接口创建的异常。

try {

  empty.orElseThrow(ValueAbsentException::new);

} catch (Throwable ex) {

  System.out.println(ex.getMessage());

}

## 

3.2、存在则执行某个动作

3.2.1、ifPresent

存在才对它做点什么

user.ifPresent(System.out::println);

//等同于

if (user.isPresent()) {

  System.out.println(user.get());

}

3.3、存在则转换成另一个Optional

3.3.1、map

public Optional map(Function<? super T, ? extends U> mapper)

如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。

1.  Optional<String> name2 = Optional.of("deff");
2.  Optional<String> s = name2.map((value) -> value.toUpperCase());
3.  System.out.println(s.orElse("No value found"));//DEFF
4.  Optional<String> name2 = Optional.ofNullable(null);
5.  Optional<String> s = name2.map((value) -> value.toUpperCase());
6.  System.out.println(s.orElse("No value found"));//No value found

//之前的做法

if(user.isPresent()) {

  return user.get().toUpperCase();

} else {

  return Collections.emptyList();

}

map  是可能无限级联的, 比如再深一层, 获得用户名的大写形式

return user.map(u -> u.getUsername())

          .map(name -> name.toUpperCase())

          .orElse(null);

3.3.2、flatMap

public Optional flatMap(Function<? super T, Optional> mapper)

如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。

flatMap与map(Funtion)方法类似,区别在于传入方法的lambda表达式的返回类型。

map方法的mapping函数返回值可以是任何类型T,而flatMap方法的mapping函数必须是Optional。

  1. Optional name = Optional.of(“Abc”);
  2. Optional upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
  3. System.out.println(upperName.orElse(“No value found”));//ABC

3.5、存在则做过滤

3.5.1、filter

检查给定的Option值是否满足某些条件。如果满足则返回同一个Option实例,否则返回空Optional。

Optional<String> longName = name.filter((value) -> value.length() > 6)

4、总结:

用了 isPresent() 处理 NullPointerException 不叫优雅, 有了 orElse, orElseGet 等, 特别是 map 方法才叫优雅.

使用 Optional 时尽量不直接调用 Optional.get() 方法, Optional.isPresent() 更应该被视为一个私有方法, 应依赖于其他像 Optional.orElse(), Optional.orElseGet(), Optional.map() 等这样的方法

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值