Java8 Optional用法和最佳实践

Java 8 Optional在实际业务场景中的运用 如果Optional仅支持非空校验,那么使用场景其实有限的,索性Optional还支持非空校验外的其它校验来过滤数据。因此本文将不会对Optional的各个方法进行详细的阐述,只会说明Optional在实际场景中如何使用,并提及一些Optional方法的注意事项。 本文描述了Optional在实际业务场景中的用法,并且涉及到了Optional的各个方法:ofNullable、filter、ifPresent、map、orElse、orElseGet等。 阅读详情

根据Oracle文档,Optional是一个容器对象,可以包含也可以不包含非null值。Optional在Java 8中引入,目的是解决 NullPointerExceptions的问题。本质上,Optional是一个包装器类,其中包含对其他对象的引用。在这种情况下,对象只是指向内存位置的指针,并且也可以指向任何内容。从其它角度看,Optional提供一种类型级解决方案来表示可选值而不是空引用。

在Optional之前

在Java 8之前,程序员将返回null而不是Optional。这种方法有一些缺点。一种是没有明确的方法来表示null可能是一个特殊值。如果我们要确保不会出现空指针异常,则需要对每个引用进行显式的空检查。

另外还有一些开发人员喜欢通过非空检查来实现业务逻辑,空对象不应该用来决定系统的行为,它们是意外的Exceptional值,应当被看成是错误,而不是业务逻辑状态。

当我们一个方法返回List集合时,应该总是返回一个空的List,而不是Null,这就允许调用者能够遍历它而不必检查Null,否则就抛出NPE。

private void getCode( User user){
        if (user != null) {
            Address address = user.getAddress();
            if (address != null) {
                Country country = address.getCountry();
                if (country != null) {
                    String code = country.getCode();
                    if (code != null) {
                        code = code.toUpperCase();
                    }
                }
            }
        }
    }

Optional

构造Optional的三种方式

public static<T> Optional<T> empty() {
  	Optional<T> t = (Optional<T>) EMPTY;
  	return t;
}

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

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


创建一个Optional类

返回一个空的Optional实例
// Creating an empty optional
Optional<String> empty = Optional.empty();

在返回一个空的{Optional}实例时,Optional的值不存在。不过,这样做可能很有诱惑力,如果对象为空,请避免与Option.empty()返回的实例的{==}比较 。因为不能保证它是一个单例,反之,应该使用isPresent()。

返回特定的非空值Optional
// Creating an optional using of

String name = "java";

Optional<String> opt = Optional.of(name);

静态方法需要一个非null参数;否则,将引发空指针异常。因此,如果我们不知道参数是否为null,那就是我们使用 ofNullable的时候,下面将对此进行介绍。

返回描述指定值的Optional,如果非空,则返回空值
// Possible null value

 Optional<String> optional = Optional.ofNullable(name());

  private  String  name(){

  String name = "Java";

  return (name.length() > 5) ? name : null;

 }

常用API

ifPresent()

如果存在值,则返回true;反之,返回false。如果所包含的对象不为null,则返回true,反之返回false。通常在对对象执行任何其他操作之前,先在Optional上调用此方法。

 Stream<String> names = Stream.of("Lamurudu", "Okanbi", "Oduduwa");
 Optional<String> longest = names
                .filter(name -> name.startsWith("L"))
                .findFirst();
longest.ifPresent(name -> {
            String s = name.toUpperCase();
            System.out.println("The longest name is "+ s);
        });
		
//The longest name is LAMURUDU

这里ifPresent() 是将一个Lambda表达式作为输入,T值如果不为空将传入这个lambda。那么这个lambda将不为空的单词转为大写输出显示。在前面names单词流寻找结果中,有可能找不到开始字母为L的单词,返回为空,也可能找到不为空,这两种情况都传入lambda中,无需我们打开盒子自己编写代码来判断,它自动帮助我们完成了,无需人工干预。

map()

使用Optional的map方法能够返回另外一个Optional

Stream<String> names = Stream.of("Lamurudu", "Okanbi", "Oduduwa");
        Optional<String> longest = names
                .filter(name -> name.startsWith("L"))
                .findFirst();
Optional<String> lNameInCaps = longest.map(String::toUpperCase);
        lNameInCaps.ifPresent(name -> {
            System.out.println("The name  is "+ name);
        });
		
//The name  is LAMURUDU

orElse()

返回值(如果存在);反之,返回其他。

Stream<String> names = Stream.of("Lamurudu", "Okanbi", "Oduduwa");
Optional<String> longest = names
                .filter(name -> name.startsWith("Q"))
                .findFirst();
String alternate = longest.orElse("Nimrod");
System.out.println(alternate);

//Nimrod

orElseGet()

返回值(如果存在);否则,调用other并返回该调用的结果。
该orElseGet() 方法类似于 orElse()。但是,如果没有Optional值,则不采用返回值,而是采用供应商功能接口,该接口将被调用并返回调用的值。

Stream<String> names = Stream.of("Lamurudu", "Okanbi", "Oduduwa");
Optional<String> longest = names
                    .filter(name -> name.startsWith("Q"))
                    .findFirst();
 String alternate = longest.orElseGet(() -> {
            return "Nimrod";
        });
 System.out.println(alternate);
 
 //Nimrod
 
orElseThrow()

orElseThrow()是在当遭遇Null时,决定抛出哪个Exception时使用

Stream<String> names = Stream.of("Lamurudu", "Okanbi", "Oduduwa");
Optional<String> longest = names
                    .filter(name -> name.startsWith("Q"))
                   .findFirst();
longest.orElseThrow(NoSuchElementStartingWithQException::new);

orElse() 和orElseGet()之间有什么区别

我们可能考虑的问题是:何时使用orElse和何时使用orElseGet?看起来可以使用orElseGet的时候,使用orElse也可以代替(因为Supplier接口没有入参),而且使用orElseGet还需要将计算过程额外包装成一个 lambda 表达式。

一个关键的点是,使用Supplier能够做到懒计算,即使用orElseGet时。它的好处是,只有在需要的时候才会计算结果。具体到我们的场景,使用orElse的时候,每次它都会执行计算结果的过程,而对于orElseGet,只有Optional中的值为空时,它才会计算备选结果。这样做的好处是可以避免提前计算结果的风险。

class User {
    // 中文名
	private String chineseName;
	// 英文名
	private EnglishName englishName;
}

class EnglishName {
    // 全名
    private String fullName;
    // 简写
    private String shortName;
}

假如我们现在有User类,用户注册账号时,需要提供自己的中文名或英文名,或都提供,我们抽象出一个EnglishName类,它包含英文名的全名和简写(因为有的英文名确实太长了)。现在,我们希望有一个User#getName()方法,它可以像下面这样实现:

class User {
    // ... 之前的内容
    public String getName1() {
        return Optional.ofNullable(chineseName)
                .orElse(englishName.getShortName());
    }
    public String getName2() {
        return Optional.ofNullable(chineseName)
                .orElseGet(() -> englishName.getShortName());
    }
}

两个版本,分别使用orElse和orElseGet。现在可以看出getName1()方法有什么风险了吗?它会出现空指针异常吗?

答案是:是的。当用户只提供了中文名时,此时englishName属性是null,但是在orElse中,englishName.getShortName()总是会执行。而在getName2()中,这个风险却没有。

博客园
腾讯云
掘金
简书

Java高级之告别空指针:Java Optional 详解与实战指南 Optional是 Java 8 引入的一种容器类,用于表示一个值存在或不存在的情况。它的设计初衷是减少代码中的空指针异常(NullPointerException),使得代码更加简洁和易读。Optional提供了一种优雅的方式来处理可能为空的值,避免了空指针异常的产生。通过合理使用Optional,可以使代码更加简洁、可读性更高。希望通过本篇文章,你能对Optional有更深入的了解,并在实际项目中灵活运用。 阅读详情

相关推荐

Optional 到底有没有用?看完源码我才知道它设计的精妙!

Optional不是银弹,但它确实:✔️ 让null检查更显式✔️ 减少✔️ 提供更优雅的链式调用✔️ 强制开发者考虑空值情况✔️ 与函数式编程完美配合关键点记住:Optional是用来处理返回值的,不是用来替代所有null检查的!希望这篇文章让你对Optional有了全新认识!下次见到Optional时,记得它的设计哲学是"显式优于隐式"。💻✨。

龚小帅的博客 1075

Java8 Optional 最佳实践

作者 |ES_her0来源 |https://xie.infoq.cn/article/e3d1f0f4f095397c44812a5be很多公众号其实都发过 Optional 的文章...

程序猿DD 790

Java8新特性之Lambda,Stream,Optional

前言 Java 8是Java自Java 5(发布于2004年)之后的最重要的版本。这个版本包含语言、编译器、库、工具和JVM等方面的十多个新特性。 1. Lambda表达式 1.1 何为Lamdba表达式 Lambda表达式理解为简洁地表示可传递的一种表达式:它没有名称,但有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表。 最简单的Lambda表达式可由逗号分隔的参数列表、->...

无意呢的博客 719

java8的Optional 详解

1、Optional 介绍 传统的写代码方式经常会遇到NullPointerException,这就需要我们在代码中经常判空。而判空的写法又会显得很累赘,这里就可以用到Optional来简化代码。 Optional是在java.util包下的一个用于代替null的一个工具类。 import java.util.Optional; Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。 Optional 类是一个可以为n

m0_58680865的博客 1万+

IAR下载Linux环境适配:入门级安装指导

详细介绍如何在Linux系统中完成iar下载与环境配置,帮助开发者快速上手IAR集成开发环境,解决常见安装问题,提升开发效率。

weixin_35754676的博客 762

手把手教你用Isaac Sim 8打造逼真光影效果:参数设置与场景应用

本文详细介绍了如何使用Isaac Sim 8打造逼真光影效果,涵盖基础参数设置、高级材质交互、专业级灯光造型技法以及复杂场景的灯光布局策略。通过实战案例和参数调优技巧,帮助用户提升虚拟场景的视觉表现,适用于数字孪生、虚拟仿真和影视特效等领域。

weixin_30836759的博客 80

Java 8 Optional 详细用法

一、简介 Optional 是一个对象容器,具有以下两个特点:     提示用户要注意该对象有可能为null     简化if else代码 二、使用介绍 1. 创建:     Optional.empty(): 创建一个空的 Optional 实例     Optional.of(T t):创建一个 Optional 实例,当 t为null时抛出异常           Optio...

旅行者 4万+

Vivado新手必看:5分钟搞定FPGA程序固化到Flash(附MCS文件生成全流程)

本文为FPGA新手详细解析了如何将程序固化到Flash存储器的完整流程。核心在于理解SRAM工艺FPGA断电易失的特性,并利用Vivado工具将比特流文件转换为Flash可识别的MCS文件。文章重点拆解了生成MCS文件的关键配置步骤、硬件连接要点,以及通过JTAG烧写Flash的实战操作,并提供了常见启动失败问题的排查清单,帮助开发者实现设计从调试到产品部署的关键跨越。

weixin_29230901的博客 352

java8 Optional理解及示例

orElseGet(lambda表达式)会在有值的时候返回值,如果没有值,它会执行作为参数传入的函数式接口(返回类型必须和Optional封装的对象是同一种类型),并将返回其执行结果。而常见的判断Optional结果的方法有,orElse()、ifPresent()、get()、empty()、map()、flatMap()。Optional的orElse()若方法不是纯计算型的,有与数据库交互或者远程调用的,都应该使用orElseGet()。值不为空时,两者都会执行参数中的函数式接口。

Cyms,BgXmSfXtsj !!!! Battle Each Moment !!!! 420

如何在OBS中添加实时时间戳:Lua脚本配置教程(附效果展示)

本文详细介绍了如何在OBS中通过Lua脚本配置实时时间戳功能,包括环境准备、脚本获取、安装配置及高级定制。适用于直播和视频录制场景,提供精准回溯和风格自定义,支持多平台适配和性能优化,是专业制作的必备技巧。

day7的博客 1044

STM32L431电池供电项目实战:用STOP2模式把功耗降到5uA以下(CubeMX配置详解)

本文详细介绍了如何在STM32L431电池供电项目中利用STOP2模式实现5μA以下的超低功耗设计。通过CubeMX配置、硬件优化和软件策略,成功将农业温湿度监测节点的待机功耗控制在4.7μA,确保CR2032电池供电下3年以上的工作寿命。文章包含完整的低功耗实现路径和实测数据,特别适合物联网边缘设备开发者参考。

weixin_30345577的博客 393

Java8 optional入门

Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。 Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。 Optional 类的引入很好的解决空指针异常。 类声明 以下是一个 java.util.Optional 类的声明: public final class Optional<T> extends Object 前言

void 412

SkillClaw:让大模型 Agent skill在多用户生态中实现群体进化的框架

随着大模型应用步入深水区,基于 LLM 的智能体(Agent)正从单一的“沙盒玩具”转变为处理真实世界复杂任务的生产力工具。然而,现有的 Agent 系统通常面临一个致命瓶颈——部署即固化。为了解决这一问题,最近有一篇新论文**《SkillClaw: Let Skills Evolve Collectively with Agentic Evolver》**提出了一种多用户生态 Agent 群体进化框架。

kakaZhui的博客 264

Java 中 Optional 的用法详解

Java 8引入的Optional<T>类为解决空指针异常提供了优雅的方案。本文详细讲解了Optional的核心用法:创建对象(of/ofNullable/empty)、判断存在性(isPresent/isEmpty)、获取值(get/orElse/orElseGet)、函数式操作(map/flatMap/filter)。文章还探讨了Optional在函数式编程和链式调用的应用,指出常见误区(如作为字段类型或过度使用get),并给出最佳实践建议:仅在返回值中使用、避免过度封装、优先orElseG

2503_92145588的博客 2198

2025.06.06【Ribo-seq】|RiboCode:基于Ribo-seq数据的全基因组翻译ORF检测工具详解与实战流程

大家好!今天我们要学习的是RiboCode——一个专为Ribo-seq(核糖体足迹测序)数据设计的高质量翻译ORF(开放阅读框)检测工具。RiboCode能够帮助我们在全基因组范围内精准识别翻译事件,发掘经典CDS之外的uORF、dORF、重叠ORF等新型翻译本,极大拓展了我们对转录本翻译潜能的认知。RiboCode 是由清华大学杨学睿课题组开发的开源软件,支持Linux/Mac平台,采用Python实现。自动化流程:一条命令即可完成注释准备、P-site定位、ORF预测。高灵敏度与特异性。

1858

华为OD机考双机位C卷 - 螺旋数字矩阵 (Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 数字螺旋矩阵(OD上机考试双机位C卷)。提供在线OJ刷题。Java、C++、Python、GO语言、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 3218

Java8中Optional的基础使用和实践

Java8中新特性Optional的基础使用

qq_39853669的博客 785

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

optional

根据Oracle文档,Optional是一个容器对象,可以包含也可以不包含非null值。Optional在Java 8中引入,目的是解决 NullPointerExceptions的问题。本质上,Optional是一个包装器类,其中包含对其他对象的引用。在这种情况下,对象只是指向内存位置的指针,并且也可以指向任何内容。相比之下,在API中返回Optional是明确的声明,其中可能没有值。如果我们要确保不会出现空指针异常,则需要对每个引用进行显式的空检查,如下所示,我们都同意这是很多样板。

qq_64071349的博客 550

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java中的Optional类详解

Optional。

weixin_53840353的博客 747

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

java中的Optional

Java 8 引入的 Optional 类用于处理可能为 null 的值,旨在减少空指针异常并提升代码可读性。其核心用法包括创建 Optional 对象(如 of、ofNullable、empty)、访问值(如 isPresent、ifPresent、orElse)、转换与过滤值(如 map、flatMap、filter),以及链式操作。最佳实践包括用 Optional 替代 null 返回值、使用链式操作简化代码、提供默认值,同时避免滥用 Optional 作为字段或过度使用。

weixin_45215156的博客 1708

Java8中Optional类的使用

Java8中Optional类的使用 1.简介 Optional类主要解决的问题是空指针异常。 本质上,这是一个包含有可选值的包装类,这以为着Optional类既可以含有对象也可以为空 在Java8之前,任何访问对象方法或者属性的调用都可能导致NullPointerException if (user != null) { Address address = user.getAddress(); if (address != null) { Country country =

拒绝熬夜啊的博客 341

深入理解Java Optional:告别NullPointerException的优雅方式

Optional是Java 8引入的一个强大工具,它帮助我们:✔️ 显式表达可能缺失的值✔️ 减少NullPointerException✔️ 编写更清晰、更安全的代码✔️ 提供丰富的函数式操作记住:Optional不是用来完全替代null的,而是为了更好地处理可能为null的情况。合理使用Optional,让你的代码更加健壮和优雅!🎉 现在就去试试Optional吧,让你的代码告别NPE烦恼!如果有任何问题,欢迎在评论区讨论~

龚小帅的博客 837

Java进阶之避免空指针Optional:用法实例(二百五十二)

本篇目的:Java进阶之Optional:用法实例基本概念Optional是Java 8引入的容器对象,用于显式表达“值可能为空”的语义,避免显式null检查与NullPointerException。功能提供of、ofNullable、empty创建;map、flatMap、filter链式操作;orElse、orElseGet、orElseThrow提供默认值;支持Stream转换。使用限制不能序列化;不应用于字段或参数;不替代异常;需正确链式调用避免get空抛。性能特性轻量级对象;

Android系统攻城狮 1386

Java 8 Stream API 与 Optional 类:深入使用与实践

Stream API 提供了一种声明式的集合处理方式,位于包。流(Stream)是对数据源(如集合、数组)的抽象,支持过滤、映射、排序、聚合等操作。核心特性函数式:通过 Lambda 表达式和方法引用实现。惰性求值:中间操作(如filtermap)延迟执行,直到终端操作(如collect)触发。不可复用:流只能消费一次。并行支持:通过实现多线程处理。操作分类中间操作filtermapsorted等,返回新流,惰性执行。终端操作collectforEachreduce等,触发计算,返回结果。流程。

lssffy的博客 1337
上一篇: docker-compose文件详解
下一篇: vue 实现动态表单点击新增 增加一行输入框
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值