Java8 之Optional 的使用

2023-11-12

     作为java8的新特性之一,可选在没有接触之前没有感受到过他的魅力,当真正的去用它才感觉到魅力之所在。可选,JAVA新增的工具类,主要是用来解决我们之前  NullPointException的问题。

    我先贴一段之前的代码,部分截取,真实业务场景中所用到的代码。

if(bidId!= null){
                //根据投标单ID,查询评标人ID --EmpId
                List <SrmBidScore> srmBidScores = srmBidExamMapper.bidScoreByBid(bidId); //查询评分表信息
                if(srmBidScores!= null){
                    for(SrmBidScore srmBidScore:srmBidScores){
                        Long empId = srmBidScore.getEmpId(); //获取评分表中的empId
                        if(empId!= null){
                            employeeList.add(employeeMapper.employeeBy(EMPID)); //根据评分表中的EMPID获取评分人信息
                        }
                    }
                    srmBidGroupListView.setEmployeeList(EmployeeList的); //将获取到的评分人,添加到评分小组信息中
                }
            }

  我们发现,每涉及到一块逻辑判断都要保证前一步所使用的参数值不能是空,否者的话下面的方法就会报NullPointException 的问题。看着是逻辑特别乱,别人在看代码时候,也不便于阅读。

   今天的主角Optional工具类就是教我们如何优雅的来解决这个问题;

一、创建Optional对象

   直接上图,会发现有三个构造方法:ofNullable(T value),of(T value),empty()

   

三者区别:

   of 

 创建一个非空Optional

  ofNullable 

 创建一个可以为空的Optional对象,与of区别就是,可以传入Null参数,如果参数为空,则调empty()方法,有值得话调用 of()方法。可以通过源码解读到。  
/**
     * Returns an {@code Optional} describing the specified value, if non-null,
     * otherwise returns an empty {@code Optional}.
     *
     * @param <T> the class of the value
     * @param value the possibly-null value to describe
     * @return an {@code Optional} with a present value if the specified value
     * is non-null, otherwise an empty {@code Optional}
     */
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

   empty

  创建一个空的Optional对象。

 所以说我们一般使用的话,就是直接使用ofNullable()来创建Optional对象实例。

二、Optional 方法

  . get 

    获取Option对象中传入的值,如果对象有值返回Optional类型的值,如果传入值为空的话,会抛出 NoSuchElementException 常;

User user = new User();
        user.setName("Tom");
        user.setAge("18");
        Optional<User> OptionalUser = Optional.ofNullable(user);
        System.out.println("-optional-ofNullable:" + OptionalUser.get());//-optional-of:User{name='Tom', age='18'}
Optional<User> OptionalUser = Optional.ofNullable(null);

        System.out.println("-optional-ofNullable:" + OptionalUser.get());//Exception in thread "main" java.util.NoSuchElementException: No value present

源码

 /**
     * If a value is present in this {@code Optional}, returns the value,
     * otherwise throws {@code NoSuchElementException}.
     *
     * @return the non-null value held by this {@code Optional}
     * @throws NoSuchElementException if there is no value present
     *
     * @see Optional#isPresent()
     */
    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");//如果传入值为空直接抛出异常
        }
        return value;
    }

.map *

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

   *map方法会将传入的lambda表达式的参数对原始的Optional值做修改;返回新的Optional实例作为map方法的返回值。

 Optional<String> OptionalString = Optional.ofNullable("abc");
        System.out.println(OptionalString.map((v) -> v.toUpperCase()));//Optional[ABC] 
源码:
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();//如果传入的Optional对象为空,直接返回Optional空对象
        else {
            return Optional.ofNullable(mapper.apply(value));//如果不为空返回mapper函数得到返回值
        }
    }

.flatMap

   如果有值返回mapper函数执行的Optional类型的值,没有值返回空Optional对象;

* flatMap方法与map方法似,区在于mapping函数的返回不同。map方法的mapping函数返回可以是任何T,而flatMap方法的mapping函数必Optional。可以通过源码比较出两者的区别。

 源码:

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));
        }
    }

.filter

从字面理解应该是对Optional对象进行过滤;

通过传入lambda表达式件对Optional实例的值进行过滤。对于filter函数我们应该传入实现了Predicate接口的lambda表达式。如果返回同一个Option实例,否则返回空Optional

Optional<String> OptionalString = Optional.ofNullable("abc");
        System.out.println(OptionalString.filter((v)->v.length()>4));//Optional.empty   v的长度小于4,返回空的Optional对象

源码:

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

.ifPresent  

  如果Optional实例有值则为其调用consumer,否不做理; ifpersent方法接受lanbda表达式作为参数

        Optional<User> OptionalUser = Optional.ofNullable(user);
        OptionalUser.ifPresent((value)->{
            System.out.println(value.getName());});//Tom
源码:
public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
    }

.orElse 

如果有值将值返回,没有值返回指定的值,这个好理解一点,只需要关注Optional实例对象是否有值就行。

Optional<String> OptionalString = Optional.ofNullable("abc");
        System.out.println("orElse:"+OptionalString.orElse("def"));//有值得情况返回abc,如果我们构造对象时传入null,则返回def

源码:

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

.orElseGet

  orElseGetorElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值。

Optional<String> OptionalString = Optional.ofNullable("abc");
        System.out.println("orElseGet:"+ OptionalString.orElseGet(()-> "wasd"));//有值情况和orElse一样返回(abc),没有的话返回lambda表达式返回的‘wasd’

源码:

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

.orElseThrow

   如果有值则将其返回,否则抛出supplier接口创建的异常;orElseThrow与orElse方法类似,返回默认值不同。

public class orElseThrowException extends Throwable{//异常类定义
    orElseThrowException() {
        super();
    }

    orElseThrowException(String msg) {
        super(msg);
    }

    @Override
    public String getMessage() {
        return "orElseThrowException";
    }

}
Optional<String> OptionalString = Optional.ofNullable(null);//这里我们在其构造对象时传入null
        try{
        OptionalString.orElseThrow(orElseThrowException::new);
        }catch (Throwable e){
            System.out.println("异常捕获");
            System.out.println(e.getMessage());//打印orElseThrowException,自定义的异常
        }
源码:
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }

      

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java8 之Optional 的使用 的相关文章

  • Java 中的 XPath 节点集

    我在 eclipse 中有这段代码 NodeSet nodes NodeSet xPath evaluate expression inputSource XPathConstants NODESET 它给我 NodeSet 上的编译时错误
  • JavaMail Gmail 问题。 “准备启动 TLS”然后失败

    mailServerProperties System getProperties mailServerProperties put mail smtp port 587 mailServerProperties put mail smtp
  • 如何查找 Android 设备中的所有文件并将它们放入列表中?

    我正在寻求帮助来列出 Android 外部存储设备中的所有文件 我想查找所有文件夹 包括主文件夹的子文件夹 有办法吗 我已经做了一个基本的工作 但我仍然没有得到想要的结果 这不起作用 这是我的代码 File files array file
  • java.io.IOException: %1 不是有效的 Win32 应用程序

    我正在尝试对 XML 文档进行数字签名 为此我有两个选择 有一个由爱沙尼亚认证中心为程序员创建的库 还有一个由银行制作的运行 Java 代码的脚本 如果使用官方 认证中心 库 那么一切都会像魅力一样进行一些调整 但是当涉及到银行脚本时 它会
  • 使用替换字符串中多个单词的最有效方法[重复]

    这个问题在这里已经有答案了 此刻我正在做 Example line replaceAll replaceAll cat dog replaceAll football rugby 我觉得那很丑 不确定有更好的方法吗 也许循环遍历哈希图 ED
  • 请求位置更新参数

    这就是 requestLocationUpdates 的样子 我使用它的方式 requestLocationUpdates String provider long minTime float minDistance LocationLis
  • 序列化对象以进行单元测试

    假设在单元测试中我需要一个对象 其中所有 50 个字段都设置了一些值 我不想手动设置所有这些字段 因为这需要时间而且很烦人 不知何故 我需要获得一个实例 其中所有字段都由一些非空值初始化 我有一个想法 如果我要调试一些代码 在某个时候我会得
  • 如何将文件透明地传输到浏览器?

    受控环境 IE8 IIS 7 ColdFusion 当从 IE 发出指向媒体文件 例如 mp3 mpeg 等 的 GET 请求时 浏览器将启动关联的应用程序 Window Media Player 我猜测 IIS 提供文件的方式允许应用程序
  • 检查 Android 手机上的方向

    如何查看Android手机是横屏还是竖屏 当前配置用于确定要检索的资源 可从资源中获取Configuration object getResources getConfiguration orientation 您可以通过查看其值来检查方向
  • 从 android 简单上传到 S3

    我在网上搜索了从 android 上传简单文件到 s3 的方法 但找不到任何有效的方法 我认为这是因为缺乏具体步骤 1 https mobile awsblog com post Tx1V588RKX5XPQB TransferManage
  • 尝试使用 Ruby Java Bridge (RJB) gem 时出现错误“无法创建 Java VM”

    我正在尝试实现 Ruby Java Bridge RJB gem 来与 JVM 通信 以便我可以运行 Open NLP gem 我在 Windows 8 上安装并运行了 Java 所有迹象 至少我所知道的 都表明 Java 已安装并可运行
  • 将 Long 转换为 DateTime 从 C# 日期到 Java 日期

    我一直尝试用Java读取二进制文件 而二进制文件是用C 编写的 其中一些数据包含日期时间数据 当 DateTime 数据写入文件 以二进制形式 时 它使用DateTime ToBinary on C 为了读取 DateTime 数据 它将首
  • Java中未绑定通配符泛型的用途和要点是什么?

    我不明白未绑定通配符泛型有什么用 具有上限的绑定通配符泛型 stuff for Object item stuff System out println item Since PrintStream println 可以处理所有引用类型 通
  • Android JNI C 简单追加函数

    我想制作一个简单的函数 返回两个字符串的值 基本上 java public native String getAppendedString String name c jstring Java com example hellojni He
  • Springs 元素“beans”不能具有字符 [children],因为该类型的内容类型是仅元素

    我在 stackoverflow 中搜索了一些页面来解决这个问题 确实遵循了一些正确的答案 但不起作用 我是春天的新人 对不起 这是我的调度程序 servlet
  • 查看Jasper报告执行的SQL

    运行 Jasper 报表 其中 SQL 嵌入到报表文件 jrxml 中 时 是否可以看到执行的 SQL 理想情况下 我还想查看替换每个 P 占位符的值 Cheers Don JasperReports 使用 Jakarta Commons
  • java迭代器内部是如何工作的? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个员工列表 List
  • 中断连接套接字

    我有一个 GUI 其中包含要连接的服务器列表 如果用户单击服务器 则会连接到该服务器 如果用户单击第二个服务器 它将断开第一个服务器的连接并连接到第二个服务器 每个新连接都在一个新线程中运行 以便程序可以执行其他任务 但是 如果用户在第一个
  • javax.persistence.Table.indexes()[Ljavax/persistence/Index 中的 NoSuchMethodError

    我有一个 Play Framework 应用程序 并且我was使用 Hibernate 4 2 5 Final 通过 Maven 依赖项管理器检索 我决定升级到 Hibernate 4 3 0 Final 成功重新编译我的应用程序并运行它
  • Jackson 将单个项目反序列化到列表中

    我正在尝试使用一项服务 该服务为我提供了一个带有数组字段的实体 id 23233 items name item 1 name item 2 但是 当数组包含单个项目时 将返回该项目本身 而不是包含一个元素的数组 id 43567 item

随机推荐

  • React-学习笔记(4-组件生命周期)

    1 旧 的生命周期函数 9个 初始化时调用的生命周期函数 初始化由 ReactDOM render 引发 constructor 就是类的构造器 最早执行的 一生只执行一次 UNSAFE componentWillMount 将要挂载 一生
  • Python爬虫入门 Urllib库的基本使用

    1 分分钟扒一个网页下来 怎样扒网页呢 其实就是根据URL来获取它的网页信息 虽然我们在浏览器中看到的是一幅幅优美的画面 但是其实是由浏览器解释才呈现出来的 实质它是一段HTML代码 加 JS CSS 如果把网页比作一个人 那么HTML便是
  • Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile

    程序报错 Failed to execute goal org apache maven plugins maven compiler plugin 2 3 2 compile 原因是缺少maven compiler plugin插件 在p
  • 【C语言】小白学浮点数

    一 浮点数的概念 浮点数也称小数或实数 C语言中采用 float 和 double 关键字来定义小数 float称为单精度浮点型 double称为双精度浮点型 另外 部分编译器支持更大精度的long double 但不是所有的编译器都支持
  • 你好请问,postman不登录联网怎么使用mock Server

    你好 Postman 具有内置的 mock server 功能 因此无需联网即可使用 要使用 mock server 请执行以下步骤 打开 Postman 应用程序 创建一个新的请求 或打开一个现有的请求 在请求的右上角 单击 更多 按钮
  • pyqt窗口控件跟随窗口大小变化而变化的方法

    要做的很简单 使用qtdesigner对设计的界面配置一下layout 页面布局 即可实现拖拽时界面中控件的放大缩小 这是布局时的几种方式 重点 用designer时要注意 不要选中多个控件然后右键选择layout 要直接在mainwind
  • 恶意代码分析实战07-02

    先peview看看exe程序 注意到这里有两个kernel32 dll 不过仔细看的话 发现其中有一个是假的 名字为kerne132 dll kernel的l被换成了1 而且出现了lab07 03 dll 看来运行这个exe的时候会加载这个
  • 常见JMeter面试题

    1 什么是JMeter JMeter是一种开源的性能测试工具 可以用于测试静态和动态资源 如Web应用程序 数据库 FTP服务器等 2 JMeter可以测试哪些类型的应用 JMeter可以测试各种类型的应用程序 包括Web应用程序 数据库服
  • Python中[:2]、[:,-1]、[-1]、[:-1]、[::-1]、[2::-1]如何使用

    数据准备 import numpy as np X np array 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 print X 形成矩阵 1 print X 1 取最后一个元素 2
  • C++检测异常assert()函数

    1 assert 函数使用 assert 一般用于debug下异常检测的功能函数 例如文件打开是否成功 函数形参传入是否理想 变量定义是否正确等 总的来说其作用是如果它的条件返回错误 则终止程序执行 原型定义 include
  • 如何用PHP写一个excel文件并导出

    其实用PHP写一个excel文件并下载下来很容易 这里我们使用了PHPExcel库去实现一个例子
  • Java基础篇--工具类操作之敏感词过滤

    编写敏感词过滤程序 说明 在网络程序中 如聊天室 聊天软件等 经常需要对一些用户所提交的聊天内容中的敏感性词语进行过滤 如 性 色情 爆炸 恐怖 枪 军火 等 这些都不可以在网上进行传播 需要过滤掉或者用其他词语替换掉 提示 将用户的聊天内
  • Python3,如何实现CPU的并行计算,那还不简单,5种方式,这篇就搞定。

    多进程实现CPU并行计算 1 引言 2 实战 2 1 多进程模式 2 1 1 定义 2 1 2 multiprocessing 2 1 3 模式 2 1 4 适用场景 2 1 4 代码示例 2 2 执行方法 2 2 1 多线程并发执行 2
  • 高德导航红绿灯为啥能读秒?

    来源 JavaEdge 1 内部员工吐露 2 真正的内幕 免责声明 任何文章不要过度深思 万事万物都经不起审视 因为世上没有同样的成长环境 也没有同样的认知水平 更 没有适用于所有人的解决方案 不要急着评判文章列出的观点 只需代入其中 适度
  • 外汇高概率一分钟交易系统

    交易系统前置 建议资金 10000美金 交易品种 黄金 交易周期 1分钟 使用指标 Ichimoku Kinko Hyo 注 只留上下Kumo 其他线隐藏 MACD MA15 MA55 交易仓位 建议每次交易 0 05手 交易入场条件 MA
  • MATLAB深度学习LSTM 标签分类classificationLayer层,YTrain的设置出错

    问题 使用matlab深度学习工具箱进行标签分类 设置XTrain为输入是n 1的元胞数组 每个元胞数据有6个特征值 YTrain输出是n 1的元胞数组 内容为标签 0 或 1 LSTM层和options设置如下 layers sequen
  • Java-进制转换

    常用的进制转换 十进制转二进制 二进制转十进制 十进制转八进制 八进制转十进制 十进制转十六进制 十六进制转十进制 如果二 八 十六之间想转换可以通过十进制做中间者 import java util Scanner import java
  • 10本编程书籍推荐!带你从入门到精通

    在看书 阅读前 一定先选择一门适合自己的编程语言 对0基础的同学 选择程序设计语言时先了解自己的学习能力 太难的语言 没有一定的基础 以及没有老师讲解 指引 太容易产生挫败感从而放弃 其次 如果自己有一点点明确的目的或需求 那么选一门对自己
  • C++ Windows上键盘拦截

    键盘捕获代码 include
  • Java8 之Optional 的使用

    作为java8的新特性之一 可选在没有接触之前没有感受到过他的魅力 当真正的去用它才感觉到魅力之所在 可选 JAVA新增的工具类 主要是用来解决我们之前 NullPointException的问题 我先贴一段之前的代码 部分截取 真实业务场