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万+

Rocky Linux 9 远程桌面配置全攻略:从零搭建XRDP服务(含防火墙设置)

本文提供了在Rocky Linux 9上从零开始配置XRDP远程桌面服务的完整指南。详细介绍了系统准备、XRDP服务安装、防火墙与SELinux安全设置、多用户性能优化以及多平台客户端连接实测。重点解决了使用Windows远程桌面协议(RDP)连接Rocky Linux时常见的配置难点与安全问题,帮助用户获得稳定高效的图形化远程访问体验。

vodka的博客 649

AI Agent ReAct架构设计模型剖析

ReAct通过"思考-行动-观察"循环运作:智能体先进行自然语言推理,再调用外部工具执行行动,观察结果后继续推理直至解决问题。这种架构提高了透明度和准确性,减少幻觉风险,使LLM能主动分解任务并利用外部数据源。实现关键在于精心设计的提示模板,引导LLM按结构化格式响应,而非依赖模型固有能力。

weixin_43939320的博客 1250

Java 8 Optional 详细用法

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

旅行者 4万+

Claude Code vs Codex

Claude Code 提供了一个生产就绪(production-ready)的实现,包含良好的错误处理、优雅的关闭逻辑、详细注释和文档,以及内置测试。Claude Code 输出了一个可运行的 Next.js + TypeScript 前端,但错过了一些设计里的黄色主题元素;Codex 则生成自己的版本,没有导出设计中的图片,也没严格遵照设计主题。Codex 完成同样功能,但更简洁直接,文档和注释少一些但功能达标。任务都用同样的提示,使用 TypeScript 实现,并在一天内完成。

weixin_49869937的博客 2388

java8 Optional理解及示例

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

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

LLC谐振变换器设计实战:从工作原理到参数设计与调试

开关电源设计是电力电子领域的核心技术,其核心目标在于提升效率与功率密度。为实现这一目标,软开关技术应运而生,它通过精心控制开关器件的电压与电流波形,使其在开通或关断瞬间实现零电压或零电流切换,从而从根本上降低开关损耗。LLC谐振变换器正是这一技术的杰出代表,它通过引入谐振网络,巧妙地实现了主开关管的零电压开关和次级整流管的零电流开关。这种拓扑结构在服务器电源、通信设备及高端显示驱动等要求高效率、高功率密度的应用场景中价值显著。本文将以半桥LLC为例,深入剖析其工作模态与增益特性,并系统阐述其参数设计、仿真验

weixin_34129696的博客 563

Python 爬虫实战:微博自动化运营工具(点赞 / 转发 / 评论 + 反封号策略)

微博作为中国最大的社交媒体平台之一,拥有庞大的用户群体和丰富的数据资源。通过 Python 爬虫技术,我们可以实现微博的自动化运营,包括点赞、转发、评论等功能,同时采取有效的反封号策略,确保账号的安全和稳定运行。

u014481728的博客 1179

Java8 optional入门

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

void 412

[关系图谱] 二.Gephi导入共线矩阵构建作者关系图谱

本文主要讲解Gephi绘制作者间的关系图谱,该软件可以广泛应用于社交网络、知识图谱分析,推荐读者使用。这是非常基础的一篇文章,重点讲解Gephi使用方法,希望对大家有所帮助。

杨秀璋的专栏 1万+

Java 中 Optional 的用法详解

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

2503_92145588的博客 2198

部署OpenClaw(ClawdBot、MoltBot)后访问localhost:18789报1008错误怎么办?

部署openclaw(曾用名ClawdBot、MoltBot)后访问localhost:18789出现1008授权错误❌?本文分享如何快速解决这个问题✅

XiaoqiangClub的博客 1万+

康耐视visionpro-CogBlobTool工具详细说明

康耐视visionpro-CogBlobTool工具详细说明

视觉人机器视觉的博客 1728

Java8中Optional的基础使用和实践

Java8中新特性Optional的基础使用

qq_39853669的博客 785

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

optional

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

qq_64071349的博客 550

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Java中的Optional类详解

Optional。

weixin_53840353的博客 747

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

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、付费专栏及课程。

余额充值