当前位置: 首页> 文旅> 文化 > 如何优雅的使用Optional类?

如何优雅的使用Optional类?

时间:2025/7/11 0:11:18来源:https://blog.csdn.net/weixin_45334346/article/details/141830493 浏览次数:0次

在项目中我们是用Optional 来判空的。

//遍历打印 userList
for (UserInfo userInfo : Optional.ofNullable(userList)
.orElse(new ArrayList<>())) {//print userInfo
}

我们通常的做法,是先判断不为空,再遍历:

if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo:userInfoList) {//print userInfo}}

这样看 你是不是会觉得比较优雅?

1. 传统的判空?

假设有一个用户信息类,它有个地址属性。

要获取用户地址的城市,会有这样的代码:

String city = userInfo.getAddress().getCity();

一般我们可以这样处理:

if (orderInfo != null) {Address address = userInfo.getAddress();if (address != null) {String city = address.getCity();}
}

使用Optional类

     String city = Optional.ofNullable(userInfo).map(User::getAddress).map(Address::getCity).orElseThrow(() ->new IllegalStateException("user or Address is null"));

可能第一眼看那个Optional优化后的代码有点生疏。多用用就会觉得很nice!

2. 常用API简介

2.1 ofNullable(T value)、empty()、of(T value)

上面使用到了 Optional.ofNullable(T value),看源码:

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

很明显!如果value为null,就返回 empty(),否则返回 of(value)函数。

那我们看看Optional的empty() 和 of(value) 函数

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

显然, empty()函数的作用就是返回EMPTY对象。

of(value) 函数会返回Optional的构造函数

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

对于 Optional的构造函数:

private Optional(T value) {this.value = Objects.requireNonNull(value);
}public static <T> T requireNonNull(T obj) {if (obj == null)throw new NullPointerException();return obj;
}
  • 当value值为空时,会报NullPointerException

  • 当value值不为空时,能正常构造Optional对象。

2.2 orElseThrow(Supplier<? extends X> exceptionSupplier)、orElse(T other) 、orElseGet(Supplier<? extends T> other)

上面的例子,我们用到了orElseThrow

 .orElseThrow(() -> new IllegalStateException("user or Address is null"));

那我们先来介绍一下它吧:

public final class Optional<T> {private final T value;public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {if (value != null) {return value;} else {throw exceptionSupplier.get();}}

很简单就是,如果value不为null,就返回value。

否则,抛出函数式exceptionSupplier的异常。

一般情况,跟orElseThrow函数功能相似的还有orElse(T other) 和 orElseGet(Supplier<? extends T> other)

public T orElse(T other) {return value != null ? value : other;
}

对于orElse,如果value不为null,就返回value ,否则返回 other

public T orElseGet(Supplier<? extends T> other) {return value != null ? value : other.get();
}

对于orElseGet,如果value不为null,就返回value ,否则返回执行函数式other后的结果。

2.3 map 和 flatMap

我们上面的例子,使用到了map(Function<? super T, ? extends U> mapper)

Optional.ofNullable(userInfo).map(User::getAddress).map(Address::getCity)

我们先来介绍一下它:

  public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {Objects.requireNonNull(mapper);if (!isPresent())return empty();else {return Optional.ofNullable(mapper.apply(value));}}public boolean isPresent() {return value != null;}

其实这段源码很简单,先是做个空值检查,接着就是value的存在性检查,最后就是应用函数并返回新的Optional

.map相似的,还有个flatMap,如下:

public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {Objects.requireNonNull(mapper);if (!isPresent())return empty();else {return Objects.requireNonNull(mapper.apply(value));}}

可以发现,它两差别并不是很大,主要就是体现在入参所接受类型不一样

2.4 isPresent 和ifPresent

有些时候,会使用到isPresentifPresent,一个就是判断value值是否为空,另外一个就是判断value值是否为空再去做一些操作

比如ifPresent:

public void ifPresent(Consumer<? super T> consumer) {if (value != null)consumer.accept(value);
}

即判断value值是否为空,然后做一下函数式的操作。

if(userInfo!=null){do(userInfo);
}

用了isPresent 可以优化为:

 Optional.ofNullable(userInfo).ifPresent(u->{do(u);
});

感觉咋样?优雅吗?

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

关键字:如何优雅的使用Optional类?

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: