关于Java 中的Optional的一些事

开始

定义一个实体类User,实现get、set方法

public class User {String name;String sex;public User(String name, String sex) {this.name = name;this.sex = sex;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}
}

定义一个UserRepository,用户仓库,实现仓库里面对数据库的user表进行username字段查询,假设user表里面有了“张三”这条数据,当查询到张三的时候,我们就会返回一“张三”对象,没有“张三”这条数据,就会返回null

public class UserRepository {public User findUserByName(String name) {if (name.equals("张三")) {return new User("张三", "男");} else {return null;}}
}

再main函数中进行引用,实例化UserRepository对象,调用里的findUserByName方法,然后打印性别,当我们查询的“张三”的是时候,我们是假设了user表里面有一条张三,那么就会返回这个张三的数据,此时打印出的性别是“男”。

public class Main {public static void main(String[] args) {UserRepository userRepository = new UserRepository();User user= userRepository.findUserByName("张三");System.out.println(user.getSex()); //男}
}

这个时候我们去查询“李四”,就会出现报错;“NullPointerException”
因为表里面只有“张三”这条数据,没有李四,就会返回为null,然后,user.getSex()就会报错,都没有这个人,你还想知道他的性别。

public class Main {public static void main(String[] args) {UserRepository userRepository = new UserRepository();User user= userRepository.findUserByName("李四");System.out.println(user.getSex());}
}

image.png


这个时候我们就需要加入if判断了,当有这个人,就是打印他的性别,
没有,就提示没有这个人。

if (user != null) {System.out.println(user.getSex());} else {System.out.println("没有这个人");}

此时我么就避免了"NullPointerException"空指针异常的问题,那我们联想下,用户进行查数据的时候,他根本不知道里面有没有他想要的数据。当数据量很大的时候,都要去使用if去判断吗,这样会显的代码非常臃肿,增加了代码的阅读性,难以维护,此时Optioanl解决了我们的问题。

Optional

可以看做一个容器,里面可以包含任何东西,也可以什么都不包含,
对UserRepository的findUserByName方法进行修改,

public Optional<User> findUserByName(String name) {if (name.equals("张三")) {return Optional.of(new User("张三", "男"));} else {return Optional.empty();}}
ifPresent和ifPresentOrElse

再main中进行修改,使用Optional容器来包含User,ifPresent方法,如果optionalUser里面含值就会执行user -> System.out.println(user.getSex()),没有就不会执行,就会报错。

public static void main(String[] args) {UserRepository userRepository = new UserRepository();Optional<User> optionalUser= userRepository.findUserByName("李四");optionalUser.ifPresent(user -> System.out.println(user.getSex()));}

如果值为空的时候,我们想执行一些其他的操作。就需要用到ifPresentOrElse方法,有值就会执行第一个参数,没有值就会执行第二个参数。

Optional<User> optionalUser= userRepository.findUserByName("李四");optionalUser.ifPresentOrElse(user -> System.out.println(user.getSex()),() -> System.out.println("没有这个人"));
//没有这个人}

Optional的使用

Optional中的静态方法

of();

于创建一个包含指定值的Optional对象,使用of方法时必须要确定是有值的,

String txt = null;
Optional<String> optionalString  = Optional.of(txt);
//就会抛出NullPointerException,
ofNullable();

创建一个包含指定值的Optional对象可以有值也可以是空的,这个时候就不会出现异常了。

String txt = null;
Optional<String> optionalString  = Optional.ofNullable(txt);
empty();

创建一个空的Optional对象。

Optional中的实例方法

orElseThrow()

不带参数

String txt = null;Optional<String> optionalString  = Optional.ofNullable(txt);optionalString.orElseThrow();
//此时就会抛出一个异常:NoSuchElementException

带参数,自定义异常

String txt = null;Optional<String> optionalString  = Optional.ofNullable(txt);optionalString.orElseThrow(() ->new RuntimeException("Optional is null"));
// 抛出的异常为Optional is null
orElse()和orElseGet()方法

直接看代码,让你更好的理解

public static void main(String[] args) {String txt = "zhangsan";Optional<String> optionalString  = Optional.ofNullable(txt);txt = optionalString.orElse(printf());System.out.println("txt的值是:" + txt);String txt1 = optionalString.orElseGet(() -> printf());System.out.println("txt1的值是:" + txt1);}public static String printf() {System.out.println("执行了printf方法");return "liSi";}
//打印结果:
//执行了printf方法
//txt的值是:zhangsan
//txt1的值是:zhangsan

此时我们可以看到:
Optional有值时,orElse会执行,而orElseGet不会执行。
既然执行了orElse方法,并且我们返回的是“liSi”,为什么打印变量txt值时候又是打印的“zhangSan”,不是“liSi”我们可以看源码:

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

其实里面的注释也说的很清楚了:If a value is present, returns the value, otherwise returns other.
存在这个值,就返回这个值,不存在,就返回其他。

现在我看下没有值的情况下是怎么样的:

public static void main(String[] args) {String txt = null;Optional<String> optionalString  = Optional.ofNullable(txt);txt = optionalString.orElse(printf());System.out.println("txt的值是:" + txt);String txt1 = optionalString.orElseGet(() -> printf());System.out.println("txt1的值是:" + txt1);}public static String printf() {System.out.println("执行了printf方法");return "liSi";}
//打印结果:
执行了printf方法
txt的值是:liSi
执行了printf方法
txt1的值是:liSi

可以看到:
Optional值为null的时候,orElse会执行,orElseGet也会执行。

我们再看下orElseGet源码

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

注释:If a value is present, returns the value, otherwise returns the result produced by the supplying function.
存在值,则返回该值,否则返回提供函数产生的结果。

总结

说白了就是传值就用orElse,需要调用方法获取就用orElseGet,
Optional有没有值的时候都会调用orElse,而orElseGet只有Optional没有值的时候才会被调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/804395.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Xinstall:专业的App下载量统计工具,让推广效果可衡量

在移动互联网时代&#xff0c;App的下载量是衡量一个应用受欢迎程度的重要指标。然而&#xff0c;很多开发者和广告主在推广App时&#xff0c;都面临着一个共同的问题&#xff1a;如何准确统计App的下载量&#xff1f;这不仅关系到推广效果的评估&#xff0c;还直接影响到广告R…

DC-1渗透测试复现

DC-1渗透测试复现 目的&#xff1a; 获取最高权限以及5个flag 过程&#xff1a; 信息打点-cms框架漏洞利用-数据库-登入admin-提权 环境&#xff1a; 攻击机&#xff1a;kali(192.168.85.136) 靶机&#xff1a;DC_1(192.168.85.131) 复现&#xff1a; 一.信息收集 扫…

Python爬虫基础快速入门

目录 前言一、什么是爬虫二、快速编写一个爬虫2.1 爬虫需要用到的库2.2 搭建项目工程2.3 安装三方库2.4 案例编写 三、爬虫实战3.1 目标分析3.2 清洗数据 四、代码改进 前言 本博客旨在分享爬虫技术相关知识&#xff0c;仅供学习和研究之用。使用者在阅读本博客的内容时&#…

Qt/C++推流组件使用说明

2.1 网络推流 公众号&#xff1a;Qt实战&#xff0c;各种开源作品、经验整理、项目实战技巧&#xff0c;专注Qt/C软件开发&#xff0c;视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发。 公众号&#xff1a;Qt入门和进阶&#xff0c;专门介绍Qt/C相关知识点学…

镗床工作台开槽的作用

镗床工作台开槽的作用主要有以下几点&#xff1a; 改善工作台的刚度和稳定性&#xff1a;开槽可以增加工作台的刚度&#xff0c;使其能够承受更大的切削力和振动力&#xff0c;提高工作台的稳定性。 方便工件夹紧和定位&#xff1a;开槽可用于夹紧和定位工件&#xff0c;使其能…

【DM8】序列

创建序列 图形化界面创建 DDL CREATE SEQUENCE "TEST"."S1" INCREMENT BY 1 START WITH 1 MAXVALUE 100 MINVALUE 1;参数&#xff1a; INCREMENT BY < 增量值 >| START WITH < 初值 >| MAXVALUE < 最大值 >| MINVALUE < 最小值…

PostgreSQL入门到实战-第十弹

PostgreSQL入门到实战 PostgreSQL数据过滤(三)官网地址PostgreSQL概述PostgreSQL中OR操作理论PostgreSQL中OR实操更新计划 PostgreSQL数据过滤(三) 了解PostgreSQL OR逻辑运算符以及如何使用它来组合多个布尔表达式。 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列…

MQ之————如何保证消息的可靠性

MQ之保证消息的可靠性 1.消费端消息可靠性保证&#xff1a; 1.1 消息确认&#xff08;Acknowledgements&#xff09;&#xff1a; 消费者在接收到消息后&#xff0c;默认情况下RabbitMQ会自动确认消息&#xff08;autoAcktrue&#xff09;。为保证消息可靠性&#xff0c;可以…

Thingsboard PE智慧运维仪表板实例(二)【智慧排口截污实例】

ThingsBoard 的仪表板是一个用于可视化和监控物联网数据的重要组件。 它具有以下特点: 1. 可定制性:用户可以根据自己的需求创建各种类型的图表、表格和指标。 2. 数据可视化:以直观的方式展示设备数据,帮助用户快速了解系统状态。 3. 实时更新:实时反映设备的最新数据…

Vant DropdownMenu 下拉菜单带搜索功能

Vant DropdownMenu 下拉菜单带搜索功能 效果图&#xff1a; 上代码&#xff1a; <van-dropdown-menu active-color"#E33737"><van-dropdown-item ref"dropdownItem"><template #title><span>{{ dropdownItem.text }}</span…

PVE下安装配置openwrt和ikuai

开端 openwrt 和 ikuai 是比较出名的软路由系统。我最早接触软路由还是因为我的一个学长要改自己家里的网络&#xff0c;使用软路由去控制网络。我听说后便来了兴致&#xff0c;也在我家搞了一套软路由系统。现在我已经做完了&#xff0c;就想着写个文章记录一下。 软路由简介…

java操作linux

文章目录 远程连接服务器执行linux命令或shell脚本介绍Process的方法相关类UML 工具类基本工具类依赖第三方的工具类 远程连接服务器 java程序远程linux服务器有两个框架分别是&#xff1a;jsch与ganymed-ssh2框架。推荐使用jsch框架&#xff0c;因为ganymed-ssh2框架不支持麒…

百度驾驶证C++离线SDK V1.1 C#接入

百度驾驶证C离线SDK V1.1 C#接入 目录 说明 效果 项目 代码 下载 说明 自己根据SDK封装了动态库&#xff0c;然后C#调用。 SDK包结构 效果 项目 代码 using Newtonsoft.Json; using OpenCvSharp; using System; using System.Collections.Generic; using System.D…

C++矩阵库Armadillo出现warning solve() system is singular错误的解决

本文介绍使用C 语言的矩阵库Armadillo时&#xff0c;出现报错system is singular; attempting approx solution的解决方法。 在之前的文章中&#xff0c;我们介绍过Armadillo矩阵库在Visual Studio软件C环境中的配置方法&#xff08;https://blog.csdn.net/zhebushibiaoshifu/a…

使用midjourney搞出一套三国人物画像!

当下已进入如火如荼的全民AI时代&#xff0c;最近体验了下midjourney&#xff0c;使用它的以图生图功能生成出来一套三国人物画像&#xff0c;和大家分享下使用心得。 使用midjourney的准备工作 下载工具 使用midjourney生产图片依赖的工具和流程&#xff0c;大致如下&#…

vue3移动端H5 瀑布流显示列表

以上效果 是之前发送的改进版 waterList <template><view class"pro-cons" v-if"data.length"><view class"cons-left"><template v-for"(item, index) in data"><template v-if"(index 1) % 2 1…

NLP在搜索召回领域中的应用场景

自然语言处理&#xff08;NLP&#xff09;在搜索召回领域中的应用场景非常广泛&#xff0c;它通过理解和分析人类语言&#xff0c;提高了信息检索的准确性和效率。以下是一些具体的应用场景&#xff1a; 1. 搜索引擎优化 NLP技术可以用于优化搜索引擎的查询处理&#xff0c;通…

【DM8】外部表

外部表是指不存在于数据库中的表。 通过向达梦数据库定义描述外部表的元数据&#xff0c;可以把一个操作系统文件当成一个只读的数据库表&#xff0c;对外部表将像普通定义的表一样访问。 外部表的数据存储在操作系统文件中&#xff0c;建立外部表的时候&#xff0c;不会产生…

下载安装JDK17(windows)

官网地址 Oracle | Cloud Applications and Cloud Platform 点击Products拉倒最下面点击java 点击右下角Download Java 选择JDK17 点击Windows&#xff0c;下载第二个 下载完成点击一下步安装就好了 认真看这段话 ​ JDK 17 binaries are free to use in production and free…

代码整洁之道【2】--函数

关于函数部分的总结 一、函数只做一件事 函数应该只做一件事、做好这件事、只做这件事。 判断函数是否不止做了一件事&#xff0c;还有一个方法&#xff0c;就是看是否能再拆出一个函数&#xff0c;该函数不仅只是单纯地重新 二、函数尽量不要太长 按照作者的理论&#xff…