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

Java 中的 Supplier:让数据生成更灵活

文章目录

        • 1. Supplier 基础:无参返回,懒加载的利器
        • 2. 与 Optional 配合,优雅地处理默认值
        • 3. 惰性初始化缓存:提升性能
        • 4. 用于随机数、时间戳等动态数据的生成
        • 5. 结合 Stream 实现动态数据流
        • 6. 与工厂模式结合,动态创建对象
        • 7. Supplier 与依赖注入结合,简化依赖管理
        • 8. 自定义 Supplier,简化业务逻辑
        • 总结:
        • 推荐阅读文章

Supplier<T> 是 Java 中一个简单但功能强大的函数式接口,用于不接受任何参数却返回结果的场景。Supplier 的妙用在于它能够灵活地生成、提供数据或对象,尤其适合懒加载、随机生成、缓存等需求。今天,我们来探讨 Supplier 的应用技巧。

1. Supplier 基础:无参返回,懒加载的利器

Supplier 的核心特点是延迟计算——它不接收参数,只有在调用 get() 时才生成数据。这种特性在懒加载场景下非常有用。例如,我们希望在需要时才加载复杂对象:

Supplier<ExpensiveObject> objectSupplier = () -> new ExpensiveObject();
ExpensiveObject obj = objectSupplier.get(); // 仅在调用 get() 时创建

这种延迟加载机制避免了不必要的开销,提升了性能。

2. 与 Optional 配合,优雅地处理默认值

在实际开发中,我们经常需要为 null 值提供默认处理。OptionalorElseGet 方法允许我们传入一个 Supplier 作为默认值生成器:

Optional<String> optionalName = Optional.ofNullable(null);
String name = optionalName.orElseGet(() -> "Default Name");

与直接使用 orElse 相比,orElseGet 只有在值不存在时才会执行 Supplier,提高了代码的性能和效率。

3. 惰性初始化缓存:提升性能

在高频调用中,通过 Supplier 实现惰性初始化缓存可以显著减少不必要的计算。假设我们要频繁获取某个对象但只需初始化一次,可以使用 SupplierOptional 实现:

public class Cache {private Supplier<Data> dataSupplier = this::loadData;private Data loadData() {System.out.println("Loading data...");return new Data("Cached data");}public Data getData() {return dataSupplier.get();}
}

这样 loadData() 只会在第一次调用 getData() 时执行,之后的数据将从缓存中直接读取,避免重复计算。

4. 用于随机数、时间戳等动态数据的生成

Supplier 特别适合动态生成不确定的值,比如随机数、时间戳等:

Supplier<Double> randomValue = Math::random;
System.out.println("Random Value: " + randomValue.get());

通过 Supplier,每次调用 get() 都能生成不同的随机数,为程序增加了灵活性。

5. 结合 Stream 实现动态数据流

Supplier 可以与 Stream.generate() 结合,生成无限数据流,适合需要动态生成数据的场景。例如,生成一组随机数或计算斐波那契数列:

Stream.generate(Math::random).limit(5).forEach(System.out::println); // 生成 5 个随机数

这种方式不仅简洁,还避免了创建重复逻辑的麻烦,方便生成大量数据流。

6. 与工厂模式结合,动态创建对象

Supplier 常用于工厂模式的实现。假设我们有一个接口 Animal 和多个实现类,我们可以用 Supplier 创建动态工厂:

Map<String, Supplier<Animal>> animalFactories = Map.of("dog", Dog::new,"cat", Cat::new
);Animal dog = animalFactories.get("dog").get();

通过 Supplier 配合工厂模式,我们可以轻松根据输入动态创建不同的对象,而不必频繁使用 if-else 逻辑。

7. Supplier 与依赖注入结合,简化依赖管理

在依赖注入中,Supplier 也能扮演重要角色。在需要延迟初始化依赖的场景下,可以通过 Supplier 实现懒加载,避免提前初始化带来的性能开销:

public class Service {private final Supplier<DatabaseConnection> connectionSupplier;public Service(Supplier<DatabaseConnection> connectionSupplier) {this.connectionSupplier = connectionSupplier;}public void processData() {DatabaseConnection conn = connectionSupplier.get();// 使用 conn 处理数据}
}

这样,Service 在真正需要数据库连接时才会获取连接,有效控制资源使用。

8. 自定义 Supplier,简化业务逻辑

假设在电商系统中,我们需要根据不同的用户生成不同的优惠券。我们可以使用 Supplier 自定义不同的生成逻辑:

public static void generateCoupon(User user, Supplier<Coupon> couponSupplier) {Coupon coupon = couponSupplier.get();System.out.println("Generated coupon for " + user.getName() + ": " + coupon);
}

使用时,只需定义不同的 Supplier 逻辑:

Supplier<Coupon> newUserCoupon = () -> new Coupon("NEWUSER10", 10);
generateCoupon(user, newUserCoupon);

这种方式让代码结构清晰,并根据不同需求定制生成逻辑。

总结:

Supplier 是 Java 函数式接口中非常灵活、简洁的一员,它不仅仅用于数据的懒加载,还可以用于生成动态数据流、依赖管理、工厂模式等场景。通过灵活应用 Supplier,可以大幅简化代码逻辑、提升性能,开发更加智能、易维护的程序。希望以上这些应用技巧能帮助你更好地使用 Supplier

推荐阅读文章
  • 由 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 枚举的几个常用技巧,你可以试着用用

相关文章:

Java 中的 Supplier:让数据生成更灵活

文章目录 1. Supplier 基础&#xff1a;无参返回&#xff0c;懒加载的利器2. 与 Optional 配合&#xff0c;优雅地处理默认值3. 惰性初始化缓存&#xff1a;提升性能4. 用于随机数、时间戳等动态数据的生成5. 结合 Stream 实现动态数据流6. 与工厂模式结合&#xff0c;动态创建…...

轻松理解操作系统 - Linux的数据块是如何储存数据的?

python入门 C入门 Linux 由于其开源、比较稳定等特点统治了服务端领域。 也因此&#xff0c;学习Linux 系统相关知识在后端开发等岗位中变得越来越重要&#xff0c;甚至可以说是必不可少的。 因为它的广泛应用&#xff0c;所以在程序员的日常工作和面试中&#xff0c;它都是经…...

青藤深度参编的终端安全国家标准正式发布

近日&#xff0c;国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告&#xff0c;由TC260&#xff08;全国网络安全标准化技术委员会&#xff09;归口&#xff0c;公安部第三研究所牵头的GB/T 29240-2024《网络安全技术 终端计算机通用安全技术规范》&…...

软考:去中心化的部署有什么特点

微服务架构被认为是去中心化的&#xff0c;因为它具有以下特点 模块化&#xff1a;微服务架构将应用程序拆分为一系列小型服务&#xff0c;每个服务都是独立的模块&#xff0c;易于维护和扩展 。这种模块化设计使得每个服务可以独立于其他服务运行&#xff0c;没有单一的控制中…...

L8.【LeetCode笔记】回文数

1.题目 https://leetcode.cn/problems/palindrome-number/description/ 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数 是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&…...

双版本android studio安装

安装双版本原因&#xff1a;不同的AS存在不兼容的情况&#xff0c;导致旧版本的项目在新项目下要各种修改&#xff0c;很讨厌&#xff0c;使用双版本&#xff0c;各使用各的就没有这样的问题了。 建议&#xff1a;先安装低版本安装版&#xff0c;再安装高版本免安装版&#xf…...

npm镜像的常用操作

查看当前配置的 npm 镜像 npm config get registry切换官方镜像 npm config set registry https://registry.npmjs.org/切换淘宝镜像(推荐) npm config set registry https://registry.npmmirror.com/切换腾讯云镜像 npm config set registry http://mirrors.cloud.tencent…...

Unity插件NodeCanvas之行为树的详细教程

文章目录 前言叶节点 Leafs1、行为 Action2、判断 Condition控制组件 Composites1、顺序执行器 Sequencer2、选择执行器 Selector3、概率选择执行器 Probability Selector4、权重选择执行器 Priority Selector5、平行执行器 Parallel6、轮流选择器 Flip Selector7、完整执行器 …...

Vue全栈开发旅游网项目(9)-用户登录/注册及主页页面开发

1.用户登录页面开发 1.查询vant组件 2.实现组件模板部分 3.模型层准备 4.数据上传 1.1 创建版权声明组件Copyright 新建文件&#xff1a;src\components\common\Copyright.vue <template><!-- 版权声明 --><div class"copyright">copyright xx…...

Flutter 的 Widget 概述与常用 Widgets 与鸿蒙 Next 的对比

一、Flutter 的 Widget 概述 Flutter 是 Google 开发的一款开源 UI 框架&#xff0c;旨在帮助开发者快速构建高性能、高保真度的移动、Web 和桌面应用程序。在 Flutter 中&#xff0c;UI 的构建完全是通过 Widget 来实现的。Widget 是 Flutter 中所有用户界面元素的基础构建块…...

微服务day04

网关 网关路由 快速入门 创建新模块&#xff1a;hm-gateway继承hmall父项目。 引入依赖&#xff1a;引入网关依赖和nacos负载均衡的依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"…...

Spring Boot 集成JWT实现Token验证详解

文章目录 Spring Boot 集成JWT实现Token验证详解一、引言二、JWT和Token基础1、什么是Token2、什么是JWT3、JWT的结构4、JWT的工作原理 三、集成JWT1、引入JWT依赖2、创建Token工具类3、创建拦截器4、注册拦截器 四、总结 Spring Boot 集成JWT实现Token验证详解 一、引言 在现…...

如何快速搭建一个spring boot项目

一、准备工作 1.1 安装JDK&#xff1a;确保计算机上已安装Java Development Kit (JDK) 8或更高版本、并配置了环境变量 1.2 安装Maven&#xff1a;下载并安装Maven构建工具&#xff0c;这是Spring Boot官方推荐的构建工具。 1.3 安装代码编辑器&#xff1a;这里推荐使用Inte…...

学习笔记:黑马程序员JavaWeb开发教程(2024.11.9)

9.1 Mybatis-基础操作-环境准备 这里也没做&#xff0c;到时候写案例&#xff0c;如果需要环境配置什么的&#xff0c;可以看看这个 9.2 Mybatis-基础操作-删除 删除需要动态获取需要删除的id&#xff0c;使用方法传参&#xff0c;#{}的方式实现 在编写的delete方法中&a…...

【软考】系统分析师第二版 新增章节 第20章微服务系统分析与设计

微服务系统是一类基于微服务架构风格的分布式系统&#xff0c;它将应用程序拆分成多个独立的小型服务&#xff0c;每个服务都运行在独立的进程中&#xff0c;并采用轻量级通信协议进行通信。这些服务可以由不同的团队开发、不同的编程语言编写&#xff0c;并且可以按需部署。微…...

抓包工具WireShark使用记录

目录 网卡选择&#xff1a; 抓包流程&#xff1a; 捕获过滤器 常用捕获过滤器&#xff1a; 抓包数据的显示 显示过滤器&#xff1a; 常用的显示过滤器&#xff1a; 实际工作中&#xff0c;在平台对接&#xff0c;设备对接等常常需要调试接口&#xff0c;PostMan虽然可以进…...

C++上机实验|多态性编程练习

1.实验目的 (1)理解多态性的概念。 (2)掌握如何用虚函数实现动态联编 (3)掌握如何利用虚基类。 2.实验内容 设计一个飞机类 plane,由它派生出歼击机类fighter和轰炸机类 bomber,歼击机类fighter 和轰炸机类bomber 又共同派生出歼轰机(多用途战斗机)。利用虚函数和虚基类描述…...

php伪协议介绍

PHP伪协议共有12种,具体如下: file:// — 访问本地文件系统http:// — 访问 HTTP(s) 网址ftp:// — 访问 FTP(s) URLsphp:// — 访问各个输入/输出流(I/O streams)php://stdin, php://stdout 和 php://stderrphp://inputphp://outputphp://memory 和 php://tempphp://filte…...

『事善能』MySQL基础 — 2.MySQL 5.7安装(一)

1、通过msi安装软件进行MySQL安装 &#xff08;1&#xff09;点击运行MySQL安装文件 &#xff08;2&#xff09;选择安装类型 我们选择自定义安装&#xff0c;点击Next。 说明 Develop Default&#xff1a;默认开发类型&#xff0c;安装MySQL服务器以及开发MySQL应用所需要的工…...

漫谈分布式唯一ID

文章目录 本系列前言UUIDDB自增主键Redis incr命令号段模式雪花算法 本系列 漫谈分布式唯一ID&#xff08;本文&#xff09;分布式唯一ID生成&#xff08;二&#xff09;&#xff1a;leaf分布式唯一ID生成&#xff08;三&#xff09;&#xff1a;uid-generator&#xff08;待完…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

python可视化:俄乌战争时间线关键节点与深层原因

俄乌战争时间线可视化分析&#xff1a;关键节点与深层原因 俄乌战争是21世纪欧洲最具影响力的地缘政治冲突之一&#xff0c;自2022年2月爆发以来已持续超过3年。 本文将通过Python可视化工具&#xff0c;系统分析这场战争的时间线、关键节点及其背后的深层原因&#xff0c;全面…...

代理服务器-LVS的3种模式与调度算法

作者介绍&#xff1a;简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们上一章介绍了Web服务器&#xff0c;其中以Nginx为主&#xff0c;本章我们来讲解几个代理软件&#xff1a…...

React、Git、计网、发展趋势等内容——前端面试宝典(字节、小红书和美团)

React React Hook实现架构、.Hook不能在循环嵌套语句中使用 , 为什么&#xff0c;Fiber架构&#xff0c;面试向面试官介绍&#xff0c;详细解释 用户: React Hook实现架构、.Hook不能在循环嵌套语句中使用 , 为什么&#xff0c;Fiber架构&#xff0c;面试向面试官介绍&#x…...

年度峰会上,抖音依靠人工智能和搜索功能吸引广告主

上周早些时候举行的第五届年度TikTok World产品峰会上&#xff0c;TikTok推出了一系列旨在增强该应用对广告主吸引力的功能。 新产品列表的首位是TikTok Market Scope&#xff0c;这是一个全新的分析平台&#xff0c;为广告主提供整个考虑漏斗的全面视图&#xff0c;使他们能够…...