惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
月光博客
月光博客
博客园 - Franky
博客园 - 三生石上(FineUI控件)
爱范儿
爱范儿
博客园 - 司徒正美
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
B
Blog RSS Feed
阮一峰的网络日志
阮一峰的网络日志
宝玉的分享
宝玉的分享
V
Visual Studio Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
IT之家
IT之家
博客园_首页
S
SegmentFault 最新的问题
A
About on SuperTechFans
Blog — PlanetScale
Blog — PlanetScale
GbyAI
GbyAI
H
Help Net Security
MongoDB | Blog
MongoDB | Blog

XINDOO

关于内卷,几个值得深想的洞察 当创作被 Skill 化:我用 AI 写了一部 320 章的长篇网文 AI第一剑,先斩程序员 AI 也会偷懒?这个 PUA 工具专治“摸鱼式编程” Gstack 深度解析:YC CEO 开源的 AI 工程团队 GitHub Trending霸榜!深度解析AI Coding辅助神器 Superpowers 深度探讨:从 OpenClaw 爆火,看 AI Agent 的真相与程序员的未来 我复刻了NotebookLM的信息图功能 我用AI写了部小说,这里是整个过程 [翻译]我在谷歌14年学到的21堂课 2万字吊打40万字:为什么我的“牛马Agent”比“数字分身”更聪明? 最近AI领域爆火的 Agent Skills 是什么? 从计算机科学的视角来看拖延症 一周改6个库后我悟了:AI时代,程序员正在退化成“甲方” 使用n8n做一个自动同步更新的Github项目问答机器人 Agent设计模式——第 20 章:优先级排序 Agent设计模式——第 1 章:提示词链 Agent设计模式——附录 D - 使用 AgentSpace 构建 Agent Agent设计模式——第 19 章:评估和监控 Agent设计模式——第 10 章:模型上下文协议 (MCP) Agent设计模式——第 21 章:探索和发现 Agent设计模式——智能体设计模式 Agent设计模式——第 11 章:目标设定和监控 Agent设计模式——第 9 章:学习和适应 Agent设计模式——第 16 章:资源感知优化 Agent设计模式——附录 G - 编码 Agent Agent设计模式——第 13 章:人机协同 Agent设计模式——第 17 章:推理技术 Agent设计模式——附录 F - 深入剖析:Agent 推理引擎的内部运作机制 Agent设计模式——章节目录
Java Optional:让你的代码更优雅
xindoo · 2023-06-25 · via XINDOO

  在Java编程中,处理null值一直是一个棘手的问题。错误的null处理可能会导致许多难以调试的运行时异常。自Java 8引入Optional类以来,它为我们提供了一种更优雅、更安全的方式来处理可能为空的值。在Java 8之前,程序员通常需要判断是否是null来避免NullPointerException,这导致代码会变得非常臃肿,而Optional类的诞生缓解了这个问题。Optional类是一个简单的容器,它可能包含某个值,或者也可能为空。它提供了一系列有用的方法来检查值是否存在,提取值(如果存在)或者提供默认值。

  使用Optional类处理null值,可以使我们的代码更简洁、更安全。相比于显式进行null检查,Optional类可以减少代码臃肿,并避免出现NullPointerException。虽然Optional并不会完全取代null,但它提供了一种更优雅的方式来表达“一个值可能不存在”这一概念。在许多场景下,Optional类都可以替代null,从而使代码更具可读性和健壮性。

  在这篇博客中,我们将深入了解Java中的Optional类及其用法。首先,我们将学习如何创建Optional实例。然后,我们将看到Optional提供的一些实用方法,比如isPresent(),get()和orElse()。我们还将讨论Optional类的一些局限性以及如何最佳地使用它。通过一些示例,我们将展示Optional类如何使代码更简洁并避免NullPointerException。最后,我们将归纳Optional类主要的优点和使用注意事项。相信通过本篇博客,你可以彻底掌握Optional类在Java 8中的使用。

什么是 Optional?

  Optional 是一个简单的容器类,用于封装可能为空的值。它可以帮助我们避免使用显式的 null 检查,并提供一种更声明式的方法来处理可能为空的值。通过使用 Optional,我们可以更容易地编写可读、可维护的代码,并减少潜在的 NullPointerException。

如何使用 Optional?

创建 Optional 对象

创建 Optional 对象有三种方法:

  1. Optional.empty(): 创建一个空的 Optional 对象。这表示没有值。
  2. Optional.of(T value): 根据给定的非空值创建一个 Optional 对象。
  3. Optional.ofNullable(T value): 根据给定的值创建一个 Optional 对象,如果值为 null,则创建一个空的 Optional 对象。
Optional<String> emptyOptional = Optional.empty(); // 空的 Optional 对象
Optional<String> nonEmptyOptional = Optional.of("Hello, world!"); // 非空的 Optional 对象
Optional<String> nullableOptional = Optional.ofNullable(null); // 空的 Optional 对象

访问 Optional 中的值

Optional 类提供了一些方法来访问其中的值:

  1. isPresent(): 如果 Optional 包含一个非空值,返回 true,否则返回 false。
  2. get(): 如果 Optional 包含一个非空值,返回该值,否则抛出一个 NoSuchElementException。
  3. orElse(T other): 如果 Optional 包含一个非空值,返回该值,否则返回一个默认值。
  4. orElseGet(Supplier<? extends T> other): 如果 Optional 包含一个非空值,返回该值,否则从提供的 Supplier 获取一个值并返回。
Optional&lt;String&gt; optional = Optional.of(&quot;Hello, world!&quot;);

if (optional.isPresent()) {
    System.out.println(optional.get()); // 输出 &quot;Hello, world!&quot;
} else {
    System.out.println(&quot;No value present&quot;);
}

String valueOrDefault = optional.orElse(&quot;Default value&quot;);
System.out.println(valueOrDefault); // 输出 &quot;Hello, world!&quot;

String valueOrGet = optional.orElseGet(() -&gt; &quot;Generated value&quot;);
System.out.println(valueOrGet); // 输出 &quot;Hello, world!&quot;

使用 Optional 的高阶方法

Optional 还提供了一些高阶方法,允许你使用 lambda 表达式进行更复杂的操作:

  1. map(Function<? super T, ? extends U> mapper): 如果 Optional 包含一个非空值,将其转换为另一个值并返回一个新的 Optional,否则返回一个空的 Optional。
  2. flatMap(Function<? super T, Optional<U>> mapper): 如果 Optional 包含一个非空值,将其转换为一个新的 Optional,否则返回一个空的 Optional。
  3. filter(Predicate<? super T> predicate): 如果 Optional 包含一个非空值且满足给定的谓词,返回 Optional,否则返回一个空的 Optional。
Optional&lt;String&gt; optional = Optional.of(&quot;Hello, world!&quot;);

Optional&lt;Integer&gt; lengthOptional = optional.map(String::length); // Optional 包含整数 13
Optional&lt;String&gt; upperCaseOptional = optional.flatMap(s -&gt; Optional.of(s.toUpperCase())); // Optional 包含字符串 &quot;HELLO, WORLD!&quot;
Optional&lt;String&gt; filteredOptional = optional.filter(s -&gt; s.startsWith(&quot;Hello&quot;)); // Optional 包含字符串 &quot;Hello, world!&quot;

复杂示例

  接下来我们来看一个更复杂的示例,来了解下Optional的优点。 假设我们有一个用户系统,其中包含用户、地址和国家信息,具体代码如下:

public class User {
    private String name;
    private Address address;
    // 构造器,getter 和 setter 省略
}

public class Address {
    private String street;
    private String city;
    private Country country;
    // 构造器,getter 和 setter 省略
}

public class Country {
    private String name;
    private String countryCode;
    // 构造器,getter 和 setter 省略
}

  假设我们需要一个方法,入参是User,返回只是这个User的contryCode,因为user、address、contry都可能为空,所以为了防止NPE我们可能会写出如下的代码。

public class UserService {
    public String getCountryCode(User user) {
        if (user == null) {
            return &quot;&quot;;
        }
        if (user.getAddress() == null) {
            return &quot;&quot;;
        }
        if (user.getAddress().getCountry() == null) {
            return &quot;&quot;;
        }
        if (user.getAddress().getCountry().getCountryCode() == null) {
            return &quot;&quot;;
        }
        return user.getAddress().getCountry().getCountryCode(); 
    }
}

  上面的代码是不是显得又臭又长,但是如果我们使用Optional,实现上面同功能的代码会变得非常简洁,具体如下:

public class UserService {
    public String getCountryCode(User user) {
        return Optional.ofNullable(user)
                .map(User::getAddress)
                .map(Address::getCountry)
                .map(Country::getCountryCode)
                .orElse(&quot;&quot;);
    }
}

相信大家可以通过上面这个实例体会到Optional的作用。

小结

  Java 语言中的 Optional 类为我们展示了一种更为优雅且安全的方式,来处理那些可能出现空值的情况。通过运用 Optional 类,你将能够编写更加简洁易懂的代码,并且避免潜在的 NullPointerException 问题。希望这篇博客文章能帮助你更加深入地理解和掌握 Java 中的 Optional 类的使用。非常感谢你抽出宝贵时间阅读本文!如果你有任何不明白的地方或者想分享的建议,请在评论区发表你的观点。我们十分期待听到你的心声!

备注:本文包含AI创作内容