Java优雅解决空指针问题源码级别刨析Optional 2

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Java优雅解决空指针问题源码级别刨析Optional

2.2.5 flatMap()应用&源码解析

刚才已经通过map()获取了学生的姓名,操作非常简单。但是当产生链路获取时,map可以使用么?

如:学生->工作->公司->公司名称。现在可能大家脑袋里已经有了一个想法,就是通过map(),代

码结构如下:

studentOptional.map(Student::getJob).map(Job:
:getCompany).map(Company::getName);

但是这段代码是无法通过编译的。因为根据map的学习,每一次在调用的时候,都会对Optional的泛型进行改变,最终产生多层Optional嵌套的结构。如下图所示:

aa3ead5980974f6abb0f8b3ac1e7bef0.png

对于这个问题的解决,Optional类中提供了另外一个获取值的方法flatMap()。它本身用于多层调用,同时对于结果它不会形成多个Optional,而是将结果处理成最终的一个类型的Optional。但是通过flatMap获取的返回值必须是Optional类型。而map则没有这个限制。

2db388d1d0c24b04aeda30061a8fd901.png

使用示例如下:

Optional<String> nameOptional =
studentOptional.flatMap(Student::getJob).flat
Map(Job::getCompany).map(Company::getName);

2.2.6 filter()应用&源码解析

在获取某个对象中的属性值时,经常会根据特定的条件进行获取。之前的编码方法通常为:

Company company = optional().get();
if("oldlu".equals(company.getName)){
  sout(company);
}

Optional类中也提供了数据过滤的方法filter()来实现这个需求。其会根据传入的条件进行判断,如果匹配则返回一个Optional对象并包含对应的值,否则返回一个空值的Optional

使用示例如下:

Optional<Company> company =
companyOptional.filter(c ->
"oldlu".equals(c.getName()));

2.2.7 orElse()应用&源码解析

在取值的时候,如果值不存在,有时我们会考虑返回一个默认值。该需求就可以通过orElse()实现。

其内部会判断值是否为null,如果不为null,则返回该值,如果为null,则返回传入的默认值。

使用示例如下:

public class Demo1 {
  public static void
getCompanyName(Student student) {
    Optional<Student> studentOptional =
Optional.ofNullable(student);
    if (studentOptional.isPresent()) {
       String value =
studentOptional.flatMap(Student::getJob).fla
tMap(Job::getCompany).map(Company::getName).
orElse("default value");
      System.out.println(value);
   }
 }
  public static void main(String[] args) {
    Company company = new Company();
    //company.setName("oldlu");
    Optional<Company> companyOptional =
Optional.of(company);
    Job job = new Job();
    job.setName("pm");
    job.setCompany(companyOptional);
    Optional<Job> jobOptional =
Optional.of(job);
    Student s1 = new Student();
    s1.setName("张三");
    s1.setJob(jobOptional);
    getCompanyName(s1);
 }
 }

2.2.8 orElseGet()应用&源码解析

orElseGet()也是用于当Optional中没有值时,返回默认值的方法。但是它与orElse()的区别在于,它是延迟加载的。只有当Optional中没有值是才会被调用。

区别示例如下:

1)当公司名称不存在

public class Demo1 {
  public static void
getCompanyName(Student student) {
    Optional<Student> studentOptional =
Optional.ofNullable(student);
    if (studentOptional.isPresent()) {
      String value1 =
studentOptional.flatMap(Student::getJob).fla
tMap(Job::getCompany).map(Company::getName).
orElse(get("a"));
      String value2 =
studentOptional.flatMap(Student::getJob).fla
tMap(Job::getCompany).map(Company::getName).
orElseGet(()->get("b"));
      System.out.println("a: 
"+value1);
      System.out.println("b: 
"+value2);
   }
 }
  public static String get(String name) {
    System.out.println(name + "执行了方
法");
    return "exec";
 }
  public static void main(String[] args) {
    Company company = new Company();
    //company.setName("oldlu");
    Optional<Company> companyOptional =
Optional.of(company);
    Job job = new Job();
    job.setName("pm");
    job.setCompany(companyOptional);
    Optional<Job> jobOptional =
Optional.of(job);
    Student s1 = new Student();
s1.setName("张三");
    s1.setJob(jobOptional);
    getCompanyName(s1);
 }
}

执行结果

a执行了方法
b执行了方法
a:  exec
b:  exec


根据上述结果可知,当公司名称不存在时,orElse()与orElseGet()都被执行了。

2)公司名称存在

public class Demo1 {
  public static void
getCompanyName(Student student) {
    Optional<Student> studentOptional =
Optional.ofNullable(student);
    if (studentOptional.isPresent()) {
      String value1 =
studentOptional.flatMap(Student::getJob).fla
tMap(Job::getCompany).map(Company::getName).
orElse(get("a"));
      String value2 =
studentOptional.flatMap(Student::getJob).fla
tMap(Job::getCompany).map(Company::getName).
orElseGet(()->get("b"));
      System.out.println("a: 
"+value1);
      System.out.println("b: 
"+value2);
   }
 }
  public static String get(String name) {
    System.out.println(name + "执行了方
法");
    return "exec";
 }
  public static void main(String[] args) {
    Company company = new Company();
    company.setName("oldlu");
    Optional<Company> companyOptional =
Optional.of(company);
    Job job = new Job();
    job.setName("pm");
    job.setCompany(companyOptional);
    Optional<Job> jobOptional =
Optional.of(job);
    Student s1 = new Student();
    s1.setName("张三");
    s1.setJob(jobOptional);
    getCompanyName(s1);
 }
}

执行结果如下:

a执行了方法
a:  oldlu
b:  oldlu
目录
相关文章
|
3月前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
105 7
|
18天前
|
前端开发 JavaScript Java
[Java计算机毕设]基于ssm的OA办公管理系统的设计与实现,附源码+数据库+论文+开题,包安装调试
OA办公管理系统是一款基于Java和SSM框架开发的B/S架构应用,适用于Windows系统。项目包含管理员、项目管理人员和普通用户三种角色,分别负责系统管理、请假审批、图书借阅等日常办公事务。系统使用Vue、HTML、JavaScript、CSS和LayUI构建前端,后端采用SSM框架,数据库为MySQL,共24张表。提供完整演示视频和详细文档截图,支持远程安装调试,确保顺利运行。
60 17
|
25天前
|
Java 调度
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
当我们创建一个`ThreadPoolExecutor`的时候,你是否会好奇🤔,它到底发生了什么?比如:我传的拒绝策略、线程工厂是啥时候被使用的? 核心线程数是个啥?最大线程数和它又有什么关系?线程池,它是怎么调度,我们传入的线程?...不要着急,小手手点上关注、点赞、收藏。主播马上从源码的角度带你们探索神秘线程池的世界...
96 0
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
|
1月前
|
JavaScript 安全 Java
智慧产科一体化管理平台源码,基于Java,Vue,ElementUI技术开发,二开快捷
智慧产科一体化管理平台覆盖从备孕到产后42天的全流程管理,构建科室协同、医患沟通及智能设备互联平台。通过移动端扫码建卡、自助报道、智能采集数据等手段优化就诊流程,提升孕妇就诊体验,并实现高危孕产妇五色管理和孕妇学校三位一体化管理,全面提升妇幼健康宣教质量。
54 12
|
13天前
|
JavaScript Java Docker
干货含源码!如何用Java后端操作Docker(命令行篇)
只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
1月前
|
人工智能 监控 安全
Java智慧工地(源码):数字化管理提升施工安全与质量
随着科技的发展,智慧工地已成为建筑行业转型升级的重要手段。依托智能感知设备和云物互联技术,智慧工地为工程管理带来了革命性的变革,实现了项目管理的简单化、远程化和智能化。
45 5
|
21天前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
|
2月前
|
JavaScript Java 测试技术
基于Java+SpringBoot+Vue实现的车辆充电桩系统设计与实现(系统源码+文档+部署讲解等)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
|
2月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
125 7
|
3月前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
189 13