当前位置: 首页 > article >正文

如何使用 CompletableFuture、Function 和 Optional 优雅地处理异步编程?


当异步遇上函数式编程,代码变得更优雅

在日常开发中,很多时候我们需要处理异步任务、函数转换和空值检查。传统的回调方式和空值判断常常让代码看起来繁琐而难以维护。幸运的是,Java 提供了 CompletableFutureFunctionOptional,这三个工具能够帮助我们以更简洁、更优雅的方式处理这些常见问题。

今天,我们将深入探讨如何利用这三者的组合来编写既清晰又高效的代码。通过简单的示例,我们一起看一下这三者是如何协作的,如何让我们远离冗长的 null 检查,告别复杂的回调地狱,并让我们的异步任务更加易于理解。


一、CompletableFuture:异步编程的利器

CompletableFuture 是 Java 8 引入的用于处理异步操作的类。它的出现让我们告别了传统的基于回调的异步编程模式。通过 CompletableFuture,我们可以以更声明式的方式处理并发任务,将复杂的任务流写得更清晰。

我们来看看一个简单的 CompletableFuture 示例:

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {return 1 + 1;
});future.thenAccept(result -> System.out.println("The result is: " + result));

在这个例子中,supplyAsync 方法启动了一个异步任务,计算了 1 + 1,然后通过 thenAccept 处理返回的结果。最重要的是,CompletableFuture 并不阻塞主线程,它允许我们在等待异步结果时继续执行其他操作。

为什么它重要:

CompletableFuture 可以显著提高程序的并发性和可读性,让异步编程变得像同步编程一样简单。它还提供了丰富的操作符(如 thenApplythenCombine 等),让任务的组合更加灵活。


二、Function:让数据转化变得轻松

Function 接口是 Java 8 引入的一个函数式接口,它能够将一个输入转化为一个输出。它常用于数据转换、函数组合等场景。

例如,我们可以通过 Function 将一个字符串转换为大写:

Function<String, String> toUpperCase = str -> str.toUpperCase();
System.out.println(toUpperCase.apply("hello"));  // 输出 "HELLO"
为什么它重要:

Function 可以帮助我们对数据进行转换,并且支持链式调用。我们可以通过 andThencompose 方法将多个转换操作连接起来,从而避免了冗长的嵌套逻辑。


三、Optional:避免 NPE(空指针异常)的利器

Optional 是 Java 8 引入的容器类,用来处理可能为空的值。它通过显式地包装值,帮助我们避免显式的 null 检查,从而让代码更加清晰、易于维护。

例如,下面是一个简单的 Optional 使用示例:

Optional<String> name = Optional.ofNullable(null);
name.ifPresent(n -> System.out.println("Hello, " + n));  // 什么也不做,因为值为 null
为什么它重要:

Optional 是防止空指针异常的良方。通过 isPresentmapflatMap 等方法,我们可以优雅地处理可能为 null 的值,而不是使用冗长的 null 检查。


四、CompletableFuture、Function 和 Optional 的组合:打造优雅的异步编程

现在,我们来结合这三者,构建一个复杂的异步场景。假设我们有一个订单查询系统,用户查询订单信息时,可能会遇到以下问题:

  • 查询结果可能为空。
  • 查询结果可能需要进一步处理(例如获取订单详情、计算总价等)。

我们通过 CompletableFuture 异步执行查询任务,利用 Function 对数据进行转换,同时通过 Optional 处理可能为 null 的情况。

场景:查询用户订单并计算订单总价
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;public class OrderProcessing {// 模拟查询订单信息的异步方法public static CompletableFuture<Optional<Order>> getOrderAsync(String orderId) {return CompletableFuture.supplyAsync(() -> {// 模拟查询过程if ("123".equals(orderId)) {return Optional.of(new Order(orderId, 100));} else {return Optional.empty();}});}// 使用 Function 处理订单信息public static Function<Order, Double> calculateTotalPrice = order -> order.getAmount() * 1.1; // 计算总价,加上 10% 税费public static void main(String[] args) {String orderId = "123";getOrderAsync(orderId).thenApply(orderOptional -> orderOptional.map(calculateTotalPrice)).thenAccept(totalPriceOpt -> totalPriceOpt.ifPresentOrElse(price -> System.out.println("订单总价是:" + price),() -> System.out.println("订单未找到")));}// 订单类static class Order {private String id;private double amount;public Order(String id, double amount) {this.id = id;this.amount = amount;}public double getAmount() {return amount;}}
}
解析:
  1. getOrderAsync:使用 CompletableFuture.supplyAsync() 异步查询订单。返回一个 Optional<Order>,避免了 null 的问题。
  2. calculateTotalPrice:使用 Function 对订单金额进行计算,将税费加成到总价中。
  3. thenApplymap:首先,我们用 thenApply 将订单处理成 Optional<Double> 类型,处理完的结果是订单总价(如果订单存在)。
  4. ifPresentOrElse:最后,我们使用 ifPresentOrElse 判断总价是否存在,若存在则打印出来,否则输出“订单未找到”。

五、总结:

通过结合 CompletableFutureFunctionOptional,我们可以更简洁、优雅地处理复杂的异步编程场景。这样做不仅提升了代码的可读性,还避免了常见的异常问题(如空指针异常)。这三者各自发挥着作用,但结合使用时能够发挥出最大的效能,让我们在开发过程中,既能提升生产力,又能减少潜在的错误。

  • CompletableFuture:让异步任务处理变得更加简单直观。
  • Function:帮助我们进行函数式数据转换和处理。
  • Optional:避免了空指针异常,使代码更安全、健壮。

这就是 CompletableFutureFunctionOptional 的强大组合,掌握它们,你就能写出更加优雅的 Java 代码!

推荐阅读文章

  • 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)

  • 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系

  • HTTP、HTTPS、Cookie 和 Session 之间的关系

  • 什么是 Cookie?简单介绍与使用方法

  • 什么是 Session?如何应用?

  • 使用 Spring 框架构建 MVC 应用程序:初学者教程

  • 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误

  • 如何理解应用 Java 多线程与并发编程?

  • 把握Java泛型的艺术:协变、逆变与不可变性一网打尽

  • Java Spring 中常用的 @PostConstruct 注解使用总结

  • 如何理解线程安全这个概念?

  • 理解 Java 桥接方法

  • Spring 整合嵌入式 Tomcat 容器

  • Tomcat 如何加载 SpringMVC 组件

  • “在什么情况下类需要实现 Serializable,什么情况下又不需要(一)?”

  • “避免序列化灾难:掌握实现 Serializable 的真相!(二)”

  • 如何自定义一个自己的 Spring Boot Starter 组件(从入门到实践)

  • 解密 Redis:如何通过 IO 多路复用征服高并发挑战!

  • 线程 vs 虚拟线程:深入理解及区别

  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别

  • 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!

  • “打破重复代码的魔咒:使用 Function 接口在 Java 8 中实现优雅重构!”

  • Java 中消除 If-else 技巧总结

  • 线程池的核心参数配置(仅供参考)

  • 【人工智能】聊聊Transformer,深度学习的一股清流(13)

  • Java 枚举的几个常用技巧,你可以试着用用

  • 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)

  • 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系

  • HTTP、HTTPS、Cookie 和 Session 之间的关系

  • 使用 Spring 框架构建 MVC 应用程序:初学者教程

  • 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误

  • Java Spring 中常用的 @PostConstruct 注解使用总结

  • 线程 vs 虚拟线程:深入理解及区别

  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别

  • 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!

  • 探索 Lombok 的 @Builder 和 @SuperBuilder:避坑指南(一)

  • 为什么用了 @Builder 反而报错?深入理解 Lombok 的“暗坑”与解决方案(二)

相关文章:

如何使用 CompletableFuture、Function 和 Optional 优雅地处理异步编程?

当异步遇上函数式编程&#xff0c;代码变得更优雅 在日常开发中&#xff0c;很多时候我们需要处理异步任务、函数转换和空值检查。传统的回调方式和空值判断常常让代码看起来繁琐而难以维护。幸运的是&#xff0c;Java 提供了 CompletableFuture、Function 和 Optional&#x…...

基于大模型的结肠癌全病程预测与诊疗方案研究

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与创新点 二、结肠癌概述 2.1 流行病学特征 2.2 发病机制与危险因素 2.3 临床症状与诊断方法 三、大模型技术原理与应用现状 3.1 大模型的基本原理 3.2 在医疗领域的应用情况 3.3 在结肠癌预测中的潜力分析 四、术前…...

操作系统概述与安装

主流操作系统概述 信创平台概述 虚拟机软件介绍与安装 windows server 安装 centos7 安装 银河麒麟V10 安装 一&#xff1a;主流服务器操作系统 &#xff08;1&#xff09;Windows Server 发展历程&#xff1a; 1993年推出第一代 WindowsNT&#xff08;企业级内核&am…...

算法设计与分析(基础)

问题列表 一、 算法的定义与特征&#xff0c;算法设计的基本步骤二、 算法分析的目的是什么&#xff1f;如何评价算法&#xff0c;如何度量算法的复杂性&#xff1f;三、 递归算法、分治法、贪婪法、动态规划法、回溯法的基本思想方法。四、 同一个问题&#xff0c;如TSP&#…...

多线程(线程安全)

一、线程安全的风险来源 1.1 后厨的「订单撞单」现象 场景&#xff1a;两服务员同时录入客人点单到同一个菜单本 问题&#xff1a; 订单可能被覆盖菜品数量统计错误 Java中的表现&#xff1a; public class OrderServlet extends HttpServlet {private int totalOrders 0…...

开发了一个b站视频音频提取器

B站资源提取器-说明书 一、功能说明 本程序可自动解密并提取B站客户端缓存的视频资源&#xff0c;支持以下功能&#xff1a; - 自动识别视频缓存目录 - 将加密的.m4s音频文件转换为标准MP3格式 - 将加密的.m4s视频文件转换为标准MP4格式&#xff08;合并音视频流&#xff09;…...

基于javaweb的SpringBoot校园服务平台系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

北京SMT贴片加工工艺优化要点

内容概要 在北京地区SMT贴片加工领域&#xff0c;工艺优化是实现高可靠电子组装的系统性工程。本文以精密化生产需求为导向&#xff0c;围绕制程关键节点展开技术剖析&#xff0c;从钢网印刷的锡膏成型控制到贴装环节的视觉定位精度&#xff0c;逐步构建全流程优化模型。通过分…...

PHYBench:首个大规模物理场景下的复杂推理能力评估基准

2025-04-23, 由北京大学物理学院和人工智能研究所等机构共同创建的 PHYBench 数据集&#xff0c;这是一个专门用于评估大型语言模型在物理场景下的复杂推理能力的高质量基准。该数据集包含 500 道精心策划的物理问题&#xff0c;覆盖力学、电磁学、热力学、光学、现代物理和高级…...

将输入帧上下文打包到下一个帧的预测模型中用于视频生成

Paper Title: Packing Input Frame Context in Next-Frame Prediction Models for Video Generation 论文发布于2025年4月17日 Abstract部分 在这篇论文中,FramePack是一种新提出的网络结构,旨在解决视频生成中的两个主要问题:遗忘和漂移。 具体来说,遗忘指的是在生成视…...

使用localStorage的方式存储数据,刷新之后,无用户消息,需要重新登录,,localStorage 与 sessionStorage 的区别

1 localStorage 与 sessionStorage 的区别: 特性localStoragesessionStorage存储时长永久存储,除非手动删除或者清空浏览器缓存会话存储,浏览器关闭后数据丢失数据生命周期持久存在,直到被明确删除(即使关闭浏览器也不会消失)当前会话结束后数据自动清空(关闭标签页或浏…...

第15章:MCP服务端项目开发实战:性能优化

第15章:MCP服务端项目开发实战:性能优化 在构建和部署 MCP(Memory, Context, Planning)驱动的 AI Agent 系统时,性能和可扩展性是关键的考量因素。随着用户量、数据量和交互复杂度的增加,系统需要能够高效地处理请求,并能够平滑地扩展以应对更高的负载。本章将探讨 MCP…...

MOA Transformer:一种基于多尺度自注意力机制的图像分类网络

MOA Transformer&#xff1a;一种基于多尺度自注意力机制的图像分类网络 引言 近年来&#xff0c;Transformer 架构在自然语言处理领域取得了巨大的成功&#xff0c;并逐渐扩展到计算机视觉领域。Swin Transformer 就是其中一个典型的成功案例。它通过引入“无卷积”架构&…...

Red:1靶场环境部署及其渗透测试笔记(Vulnhub )

环境介绍&#xff1a; 靶机下载&#xff1a; https://download.vulnhub.com/red/Red.ova 本次实验的环境需要用到VirtualBox&#xff08;桥接网卡&#xff09;&#xff0c;VMware&#xff08;桥接网卡&#xff09;两台虚拟机&#xff08;网段都在192.168.152.0/24&#xff0…...

从 Java 到 Kotlin:在现有项目中迁移的最佳实践!

全文目录&#xff1a; 开篇语 1. 为什么选择 Kotlin&#xff1f;1.1 Kotlin 与 Java 的兼容性1.2 Kotlin 的优势1.3 Kotlin 的挑战 2. Kotlin 迁移最佳实践2.1 渐进式迁移2.1.1 步骤一&#xff1a;将 Kotlin 集成到现有的构建工具中2.1.2 步骤二&#xff1a;逐步迁移2.1.3 步骤…...

Java Collections工具类指南

一、Collections工具类概述 java.util.Collections是Java集合框架中提供的工具类&#xff0c;包含大量静态方法用于操作和返回集合。这些方法主要分为以下几类&#xff1a; 排序操作查找和替换同步控制不可变集合特殊集合视图其他实用方法 二、排序操作 1. 自然排序 List&…...

深入详解人工智能数学基础——概率论中的KL散度在变分自编码器中的应用

🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…...

测试模版x

本篇技术博文摘要 &#x1f31f; 引言 &#x1f4d8; 在这个变幻莫测、快速发展的技术时代&#xff0c;与时俱进是每个IT工程师的必修课。我是盛透侧视攻城狮&#xff0c;一名什么都会一丢丢的网络安全工程师&#xff0c;也是众多技术社区的活跃成员以及多家大厂官方认可人员&a…...

Openharmony 和 HarmonyOS 区别?

文章目录 OpenHarmony 与 HarmonyOS 的区别&#xff1a;开源生态与商业发行版的定位差异一、定义与定位二、技术架构对比1. OpenHarmony2. HarmonyOS 三、应用场景差异四、开发主体与生态支持五、关键区别总结六、如何选择&#xff1f;未来展望 OpenHarmony 与 HarmonyOS 的区别…...

uniapp 仿小红书轮播图效果

通过对小红书的轮播图分析&#xff0c;可得出以下总结&#xff1a; 1.单张图片时容器根据图片像素定高 2.多图时轮播图容器高度以首图为锚点 3.比首图长则固高左右留白 4.比首图短则固宽上下留白 代码如下&#xff1a; <template><view> <!--轮播--><s…...

让Docker端口映射受Firewall管理而非iptables

要让Docker容器的端口映射受系统防火墙(如firewalld或ufw)管理&#xff0c;而不是直接通过iptables&#xff0c;可以按照以下步骤配置&#xff1a; 方法一&#xff1a;禁用Docker的iptables规则 &#xff08;1&#xff09;编辑Docker配置文件&#xff1a; vi /etc/docker/da…...

R/G-B/G色温坐标系下对横纵坐标取对数的优势

有些白平衡色温坐标系会分别对横纵坐标取对数运算。 这样做有什么优势呢? 我们知道对数函数对0-1之间的因变量值具有扩展作用。即自变量x变化比较小时,经过对数函数作用后可以把因变量扩展到较大范围内,即x变化较小时,y变化较大,增加了识别数据的识别性。 由于Raw数据中的…...

AI赋能安全调度系统:智能升级与功能跃迁

安全调度系统通过AI技术的深度整合&#xff0c;实现了从传统监控到智能决策的质变升级。这种智能化转型不仅提升了系统的响应速度和处理精度&#xff0c;更重塑了整个安全管理的运行范式。以下是AI技术为安全调度系统带来的核心功能强化&#xff1a; 智能风险识别与预警能力跃…...

数据结构与算法(十二):图的应用-最小生成树-Prim/Kruskal

相关文献&#xff1a; 数据结构与算法(一)&#xff1a;基础理论 数据结构与算法(二)&#xff1a;线性表的实现 数据结构与算法(三)&#xff1a;线性表算法设计练习 数据结构与算法(四)&#xff1a;斐波那契数列 数据结构与算法(五)&#xff1a;LRU 数据结构与算法(六)&#xff…...

项目——高并发内存池

目录 项目介绍 做的是什么 要求 内存池介绍 池化技术 内存池 解决的问题 设计定长内存池 高并发内存池整体框架设计 ThreadCache ThreadCache整体设计 哈希桶映射对齐规则 ThreadCache TLS无锁访问 CentralCache CentralCache整体设计 CentralCache结构设计 C…...

系统与网络安全------弹性交换网络(2)

资料整理于网络资料、书本资料、AI&#xff0c;仅供个人学习参考。 Eth-Trunk 组网中经常会遇到的问题 链路聚合技术 概述 Eth-Trunk&#xff08;链路聚合技术&#xff09;作为一种捆绑技术&#xff0c;可以把多个独立的物理接口绑定在一起&#xff0c;作为一个大带宽的逻辑…...

信息系统项目管理工程师备考计算类真题讲解八

一、风险管理 示例1&#xff1a;EMV 解析&#xff1a;EMV(Expected Monetary Value)预期货币价值。一种定量风险分析技术。通过考虑各种风险事件的概率及其可能带来的货币影响&#xff0c;来计算项目的预期价值。 可以用下面的较长进行表示&#xff1a; 水路的EMV:7000*3/4(7…...

C# 结构(Struct)

原文&#xff1a;C# 结构&#xff08;Struct&#xff09;_w3cschool 在 C# 中&#xff0c;结构是值类型数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。struct 关键字用于创建结构。 结构是用来代表一个记录。假设您想跟踪图书馆中书的动态。您可能想跟踪每本…...

vim的.vimrc配置

使用背景 没想到有一天会用上这玩意。 有时候处于安全等考虑&#xff0c;服务器无法使用vscode直连&#xff0c;虽然大部分操作使用async利用云开发机同步即可&#xff0c;但是偶尔想要方便的修改远端服务器的代码&#xff0c;就可能临时使用vim&#xff0c;所以还是记录下自己…...

优化uniappx页面性能,处理页面滑动卡顿问题

问题&#xff1a;在页面遇到滑动特别卡的情况就是在页面使用了动态样式或者动态类&#xff0c;做切换的时候页面重新渲染导致页面滑动卡顿 解决&#xff1a;把动态样式和动态类做的样式切换改为通过获取元素修改样式属性值 循环修改样式示例 bannerList.forEach((_, index)…...