首页 > 其他分享 >如何优雅的使用Optional类?

如何优雅的使用Optional类?

时间:2024-09-02 21:23:23浏览次数:6  
标签:return value 优雅 如何 userInfo null Optional public

在项目中我们是用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实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

标签:return,value,优雅,如何,userInfo,null,Optional,public
From: https://blog.51cto.com/u_16502039/11900815

相关文章

  • 【新】如何编写一个C++程序来整蛊你的好基友?
    【新版】如何编写一个C++程序来整蛊你的好基友呢?如何编写一个C++程序来整蛊你的好基友整蛊按照危险性来排序3星类1.一直输出,换行2.一直输出,不换行3.给控制台换一个颜色(较有威慑力)颜色代码4.扫盘(配上第三个效果更好,可以用来装B)4星类(含部分解药)弹窗类弹窗代码按下反......
  • 人情社会:就是学会如何安排一场完美的饭局
    在中国,饭局不仅仅是满足口腹之欲的聚会,它更是一种深具文化内涵的社交方式。一场完美的饭局,不仅能够让宾客尽兴而归,还能在无形中达成主人的种种目的。那么,如何精心策划与安排这样一场饭局呢?关键在于理解“饭局”二字的深层含义——它不仅仅在于“饭”,更在于“局”。今天酱酒亮哥......
  • 如何用MySQL设计一个高效的关系数据库架构
    如何用MySQL设计一个高效的关系数据库架构设计一个高效的关系数据库架构是确保数据库性能、可维护性和扩展性的关键。一个良好的数据库设计不仅能够提高查询效率,还能减少数据冗余,降低维护成本。以下将详细介绍如何用MySQL设计一个高效的关系数据库架构,包括设计原则、规范......
  • 如何训练一个 LSTM 网络以解决特定的序列预测问题(含代码示例)
    关注我,持续分享逻辑思维&管理思维&面试题;可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导;推荐专栏《10天学会使用asp.net编程AI大模型》,目前已完成所有内容。一顿烧烤不到的费用,让人能紧跟时代的浪潮。从普通网站,到公众号、小程序,再到AI大模型网站。干货满满。学成后可......
  • 【Windows】windows server如何实现 ps aux | grep xxx 方式过滤出要看到的进程信息
    在WindowsServer中,可以使用PowerShell或命令提示符(cmd.exe)来实现类似Linux中psaux|grepxxx的功能。具体来说,可以使用PowerShell的Get-Process命令来获取进程信息,并使用管道(|)和筛选命令来过滤出特定的进程信息。使用PowerShellPowerShell提供了非常强大的命令行工具,......
  • 开源优雅的API交互工具 HTTPie CLI
    #HTTPie CLI:现代、用户友好的命令行HTTP客户端 - 精选真开源,释放新价值。概览HTTPie CLI 是一款专为API时代设计的命令行HTTP客户端,以其简洁明了的语法和丰富的功能集,为开发者和系统管理员提供了一种高效与HTTP服务交互的方式。它支持JSON格式的自动解析和生成,使得与RESTfu......
  • kimi:如何分析是哪个接口调用了最多次的operator new[]接口?
    如何分析是哪个接口调用了最多次的operatornew[]接口?重载operatornew[]:你可以在你的程序中重载operatornew[],记录每次调用时的调用栈信息。#include<iostream>#include<fstream>#include<new>#include<cstdlib>#include<execinfo.h>//包含backtrace函数#inc......
  • 如何利用 UDP-6-N3-GalNAc 来追踪和研究糖基化在细胞中的发生位置和过程?
    如何利用UDP-6-N3-GalNAc来追踪和研究糖基化在细胞中的发生位置和过程?UDP-6-N3-GalNAc是一种具有特定化学结构的分子。一、分子结构与组成它包含尿苷二磷酸(UDP)、N3(叠氮基团)和GalNAc(N-乙酰半乳糖胺)。其中,UDP作为一种重要的辅酶,在许多生物化学反应中起着传递能量和基团......
  • 如何把钓鱼邮件“拒之门外”?试试U-Mail邮件安全网关
    在当今信息化时代,互联网的发展使得人与人之间的沟通变得更加便捷和频繁,通过互联网,人们可以随时与远在他处的朋友或者业务伙伴进行交流。同时也给不法之徒利用互联网进行欺诈和违法犯罪提供了可乘之机。钓鱼邮件就是不法之徒利用网络实施不法行为的一种常见手段,犯罪分子伪装成同事、......
  • 在Python中如何执行语句?
    Python是一种高级编程语言,具有简洁、易读的语法结构,广泛应用于数据分析、机器学习、web开发、人工智能、游戏开发等领域。而在Python中,语句是构建程序的基本单元,通过语句来实现具体的功能操作,那么Python如何执行语句?具体请看下文。Python使用以下方法来执行语句:1、解......