【JAVA】深入理解Hutool中的Pair、Triple和Tuple:组合数据的新方式,方法返回多个值,嘎嘎香,谁用谁知道,比原生好用更强大
Hutool 是一个开源的 Java 工具库,提供了丰富且实用的功能,旨在减少 Java 程序员在日常开发中重复造轮子的工作。在 Hutool 中,Pair、Triple 和 Tuple 是三种用于组合和存储不同数量相关联数据的类。以下是这三个类的简介:
1、添加依赖
<dependency><groupId>org.dromara.hutool</groupId><artifactId>hutool-all</artifactId><version>6.0.0-M12</version>
</dependency>
2、Pair、Triple 和 Tuple介绍
2.1、 Pair
Pair 用于存储两个元素的键值对,通常包含一个键和一个值。这种结构在需要将两个相关联的数据项作为一个单元进行操作时非常有用。
- 键值结构:提供键(left)和值(right)两种数据的存储。
- 不可变性:一旦创建,
Pair中的值不能被修改,保证了数据的不可变性和线程安全。 - 使用场景:存储用户ID和名称、记录商品价格和库存数量等。
2.2、 Triple
Triple 类似于 Pair并继承于Pair,但它可以存储三个元素。它同样提供了不可变性,确保数据的稳定性。
- 三个元素:可以看作是
Pair的组合。 - 不可变性:值不可修改。
- 使用场景:用于存储更复杂的数据关系,如姓名、年龄和性别,或者订单的ID、价格和状态等。
2.3、 Tuple
Tuple 是一种在 Java 中使用的不可变数据结构,用于存储任意数量的元素。与 Pair 和 Triple 不同,Tuple 不强制要求有固定的元素数量,可以存储多个元素,但它不支持修改、添加或删除元素。
- 不可变性:
Tuple对象创建后,其内部的元素是不可变的,这意味着一旦创建,就不能更改Tuple中的任何元素。 - 可存储的元素数量:
Tuple可以存储任意数量的元素,但创建Tuple时必须指定要存储的元素数量。 - 使用场景:适用于需要存储多个值但不关心键值对结构的情况,例如订单详情、配置参数等。
3、 Pair 的创建和修改
3.1、 创建 Pair
// 用户名修改为 "Alice Smith"
userPair = Pair.of(userPair.getLeft(), "Alice Smith");
int userId = userPair.getLeft();
String userName = userPair.getRight();
3.2、修改 Pair 中的值
// 创建一个新的 Pair,值已被修改
Pair<Integer, String> newPair = Pair.of(pair.getLeft(), "banana");
3.3、 使用场景示例
Pair 类在以下场景下特别适用,因为它提供了一个简单的方式来组合和操作两个相关联的数据项,特别是方法需要返回两个值得情况下特别好用,嘎嘎香:
-
键值对操作:当你需要将两个数据项关联起来,其中一个作为键(key),另一个作为值(value)时,
Pair类非常有用。例如,用户ID和用户姓名、商品ID和价格等。Pair<Integer, String> userIdAndName = Pair.of(1, "Alice"); -
映射关系:
Pair类可以用来表示简单的映射关系,如单词和翻译、文件路径和描述等。Pair<String, String> wordTranslation = Pair.of("hello", "你好"); -
元数据存储:当你需要存储与某个实体相关的两个元数据项时,
Pair类可以用来封装这些信息。Pair<String, String> metaData = Pair.of("title", "Example Title"); -
返回结果:在函数或方法返回两个相关结果时,
Pair类提供了一种比基本数据类型数组更具有描述性和类型安全的方式。Pair<Integer, Boolean> calculationResult = Pair.of(42, true); -
状态封装:在某些情况下,你可能需要将两个状态相关的字段封装在一起,
Pair类可以用来实现这一点。Pair<String, String> statusPair = Pair.of("status", "active"); -
筛选条件:在处理集合或列表时,
Pair类可以用来存储筛选条件,例如在实现自定义的过滤逻辑时。Pair<String, String> filterCondition = Pair.of("field", "value"); -
排序辅助:在需要对列表进行排序,同时需要根据两个条件进行比较时,
Pair类可以用来封装排序的键。List<Pair<String, Integer>> sortedList = lists.stream().map(name -> Pair.of(name, calculateScore(name))).sorted(Comparator.comparing(Pair::getRight)).collect(Collectors.toList()); -
并发编程:由于
Pair类是不可变的,它可以在并发环境中安全地共享,这在需要实现线程安全的程序时非常有用。
Pair 类的设计简洁且易于使用,它为处理简单的数据关联提供了轻量级和类型安全的解决方案。在任何需要将两个数据项作为一对进行操作的场景中,Pair 类都是一个很好的选择。
4、 Triple 的使用
riple 和 Tuple 的使用与 Pair 类似
- 获取 Triple 中的值
Triple<String, Integer, Boolean> triple = Triple.of("name", 25, true);
String name = triple.getLeft();
int age = triple.getMiddle();
boolean isActive = triple.getRight();
Triple 类在以下场景下比较适用,因为它允许你存储和操作三个相关联的数据项,这些数据项可能共同描述了一个完整的概念或实体:
-
复杂实体描述:当你需要表示一个包含三个不同属性或状态的实体时,
Triple非常有用。例如,一个学生的记录可能包含姓名、年龄和成绩。Triple<String, Integer, Integer> studentInfo = Triple.of("Alice", 20, 90); -
关联数据集:在处理需要三个字段来关联多个数据集时,
Triple类可以帮助你保持数据的一致性和清晰性。例如,你可以使用Triple来存储两个日期(开始和结束)以及与这两个日期相关的值。Triple<LocalDate, LocalDate, Double> salesData = Triple.of(startDate, endDate, salesAmount); -
业务规则参数:在某些业务逻辑中,你可能需要三个参数来定义一个规则或条件。
Triple可以用来封装这些参数。Triple<Double, Double, Double> discountRule = Triple.of(minimumAmount, maximumAmount, discountRate); -
配置数据:如果你有一个配置文件或数据库表,其中需要三个字段来存储配置信息,
Triple可以用来封装这些配置数据。Triple<String, String, Integer> databaseConfig = Triple.of("host", "localhost", 3306); -
数据聚合:在需要将三个相关数据项聚合为一个单元时,
Triple类可以简化代码并减少错误。Triple<Integer, Integer, Integer> scoreStats = Triple.of(minScore, maxScore, averageScore); -
映射和转换:在数据处理和转换过程中,当需要将三个不同的源数据项映射到三个不同的目标数据项时,
Triple类可以帮助你保持数据的一致性。Triple<String, Integer, String> keyToValueMap = Triple.of("key1", 1, "value1");
总之,Triple 类在需要表示或操作三个独立但相关联的数据项时非常有用,它可以提供一种简洁、类型安全的方式来处理这些数据。
5、 Tuple 的使用
Tuple 类在 Java 中用于存储一组任意数量的元素
- 获取 Tuple 中的值
Tuple tuple = Tuple.of(1, "apple", true);
int id = tuple.get(0);
String name = tuple.get(1);
boolean active = tuple.get(2);
-
函数返回值:当需要一个方法返回多个值,但这些值之间没有明确的键值关系时,可以使用
Tuple。// 假设 calculateSum 返回三个整数值:总和、最大值和最小值 Tuple<Integer, Integer, Integer> sumMinMax = calculateSum(1, 2, 3, 4, 5); -
参数封装:当你需要将多个参数组合在一起传递给一个方法或构造器时,
Tuple可以用来封装这些参数。Tuple<String, Integer, Boolean> userInfo = Tuple.of("Alice", 25, true); -
事件或消息:在处理事件驱动或消息传递系统时,
Tuple可以用来封装事件或消息的多个相关属性。Tuple<String, String, Integer> messageInfo = Tuple.of("SMS", "Your order has been shipped", 123456); -
配置数据:在处理配置文件或系统设置时,
Tuple可以用来存储多个配置项。Tuple<String, String, String> appConfig = Tuple.of("host", "http://localhost:8080", "username", "admin"); -
复合统计:在需要进行复杂的统计计算时,
Tuple可以用来封装多个相关的统计结果。Tuple<Integer, Double, Double> stats = Tuple.of(count, average, standardDeviation); -
数据导出:在使用数据导出功能时,
Tuple可以用来封装一行或多行数据。Tuple<String, String, String, String> exportRow = Tuple.of("id", "name", "email", "status"); -
自定义对象:当需要创建一个包含多个字段的自定义对象,但这些字段之间没有直接的关联关系时,
Tuple可以用来构建这个对象。Tuple<Integer, Double, String> productDetails = Tuple.of(productId, price, description); -
通用数据结构:在那些需要灵活存储多个数据项,但不需要特定键值对结构的场景中,
Tuple是一个通用且灵活的选择。Tuple<String, Integer, Double, Boolean> complexData = Tuple.of("name", 123, 456.78, false);
Tuple 类的优点在于它的灵活性和简单的使用方式,它允许开发者以非常直观的方式组合和传递多个数据项。然而,由于 Tuple 没有提供明确的键名称,因此在使用时可能需要更多的上下文信息或者通过位置索引来访问内部的元素。
相关文章:
【JAVA】深入理解Hutool中的Pair、Triple和Tuple:组合数据的新方式,方法返回多个值,嘎嘎香,谁用谁知道,比原生好用更强大
Hutool 是一个开源的 Java 工具库,提供了丰富且实用的功能,旨在减少 Java 程序员在日常开发中重复造轮子的工作。在 Hutool 中,Pair、Triple 和 Tuple 是三种用于组合和存储不同数量相关联数据的类。以下是这三个类的简介: 1、添…...
modulepreload 对性能的影响
一、正面影响 减少加载时间: modulepreload 可以让浏览器提前下载模块脚本,减少页面加载时间,特别是对于依赖较多的复杂应用。这种预加载可以让浏览器在遇到 modulepreload 链接时立即开始下载,而不是等到实际需要时才下载提升用…...
问题:向上对齐对象的快捷键是: #学习方法#笔记
问题:向上对齐对象的快捷键是: A、T B、L C、R D、W 参考答案如图所示...
C# 4.List
comboBox使用的下拉框 Lsit 列表 1 创建List对象 List<string> list new List<string>(); 2 Add给list 添加元素 list.Add("吃饭"); list.Add("睡觉"); list.Add("打豆豆"); 3 删除一个元素 list.Remove("吃饭"); // 删…...
界面控件DevExpress Blazor UI v24.1 - 发布全新TreeList组件
DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验,这个UI自建库提供了一套全面的原生Blazor UI组件(包括Pivot Grid、调度程序、图表、数据编辑器和报表等)。 DevExpress Blazor控件目前已经升级…...
docker默认存储地址 var/lib/docker 满了,换个存储地址操作流程
1. 查看docker 存储地址 docker info如下 var/lib/docker2、查看内存大小 按需执行 df -h 找超过100M的大文件 find / -type f -size 100M -exec ls -lh {} \; df -Th /var/lib/docker 查找这个文件的容量 df -h 查找所有挂载点 du -hs /home/syy_temp/*1、df -h 2、sud…...
SpringMVC的底层工作原理?
1.用户发送请求至前端控制器DispatcherServlet. 2.DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器 3.HandlerMapping找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器及处理器拦截器(如果有则生成)一并返回给DispatcherSe…...
PyTorch 深度学习实践-处理多维特征的输入
视频指路 参考博客笔记 参考笔记二 通过多个线性模型来模拟非线性的空间变换,矩阵计算就是不同维度之间的空间转换 说明:1、乘的权重(w)都一样,加的偏置(b)也一样。b变成矩阵时使用广播机制。神经网络的参数w和b是网络需要学习的,…...
常见逻辑漏洞举例
文章目录 简介用户名可枚举验证码可绕过/验证码回传越权访问任意密码修改验证码回传订单金额任意修改URL跳转漏洞短信轰炸找回密码还有很多逻辑漏洞,其实并没有什么技巧,要分析清楚他的业务逻辑,可能很多正常的流程中就存在着逻辑漏洞。 简介…...
FastAPI 学习之路(五十九)封装统一的json返回处理工具
在本篇文章之前的接口,我们每个接口异常返回的数据格式都不一样,处理起来也没有那么方便,因此我们可以封装一个统一的json。 from fastapi import status from fastapi.responses import JSONResponse, Response from typing import Unionde…...
tg小程序前端-dogs前端源码分析
tg小程序前端-dogs前端源码分析 前端源码 index.html <!DOCTYPE html> <html lang="en"><head><script src="https://telegram.org/js/telegram-web-app.js" onload="window.Telegram.WebApp.expand(); window.Telegram.WebA…...
Linux——多路复用之select
目录 前言 一、select的认识 二、select的接口 三、select的使用 四、select的优缺点 前言 在前面,我们学习了五种IO模型,对IO有了基本的认识,知道了select效率很高,可以等待多个文件描述符,那他是如何等待的呢&a…...
探索.NET内存之海:垃圾回收的艺术与实践
简述 在.NET的广阔天地中,内存管理如同航海中的罗盘,指引着程序的稳健运行和性能的极致优化。作为软件工程师,我们时常在代码的海洋中航行,而内存管理则是确保航程顺畅的关键。本文将带您深入.NET的内存管理世界,一探垃…...
路由数据获取及封装方法
数据库设计 自联表 定义tree字段 public class LabelValue{public int label { get; set; }public string? value { get; set; }public List<LabelValue> children { get; set; }}获取路由方法 public Response<object> getMenuList() {Response<object>…...
Visual Studio Code 实现远程开发
Background 远程开发是指开发人员在本地计算机上进行编码、调试和测试,但实际的开发环境、代码库或应用程序运行在远程服务器上。远程开发的实现方式多种多样,包括通过SSH连接到远程服务器、使用远程桌面软件、或者利用云开发环境等。这里我们是使用VSCo…...
基于STM32设计的人体健康监测系统(华为云IOT)(189)
基于STM32设计的人体健康监测系统(华为云IOT)(189) 文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】整体构架【3】ESP8266模块配置【4】上位机开发思路【5】供电方式1.3 项目开发背景【1】选题的意义【2】可行性分析【…...
开源防病毒工具--ClamAV
产品文档:简介 - ClamAV 文档 开源地址:Cisco-Talos/clamav:ClamAV - 文档在这里:https://docs.clamav.net (github.com) 一、引言 ClamAV(Clam AntiVirus)是一个开源的防病毒工具,广泛应用…...
【网络】Socket编程
文章目录 正确理解端口号理解源IP地址和目的IP地址认识端口号端口号和进程ID 理解Socket网络字节序socket编程接口创建socket套接字bind绑定套接字listen建立监听accept接受连接connect建立连接sendto发送数据接收数据close关闭套接字 sockaddr结构体 正确理解端口号 理解源IP…...
【鸿蒙学习笔记】舜和酒店项目开发
这里写目录标题 前期准备1. 环境准备2. 开发工具准备 创建项目1. 使用 deveco-studio 创建 ShunHeHotel 项目2. 把ShunHeHotel 项目使用git进行版本控制3. 提交第1个commit,Alt0 → 输入commit message → 提交4. 查看已经提交的第一个提交5. gitcode 创建同名远程项…...
再进行程序的写时,不要使用eval函数——内建函数eval的坏处!!!!!!!!
一、安全性问题 执行任意代码: eval函数可以执行任意的Python表达式,包括算术运算、逻辑判断、字符串操作等,甚至可以访问当前作用域中的所有变量和函数。这意味着,如果eval处理的字符串来自不可信的源(如用户输入、外…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
