Java 中基于条件动态决定字段参与分组的实现方法

在 Java 的 Stream API 中,Collectors.groupingBy()方法为数据分组提供了强大的支持。通过它,我们可以轻松地将集合中的元素按照某个属性进行分组,比如按照商品类别、日期等。然而,在实际业务场景中,有时需要根据特定条件来决定哪些字段参与分组,这就需要我们采用一些更灵活的策略。接下来,本文将结合具体代码示例,深入探讨几种实现动态决定字段参与分组的方法。​

一、使用复合键并在其中应用条件逻辑​

复合键是一种将多个属性组合起来作为分组依据的方式,在构建复合键的过程中,可以灵活地加入条件判断,从而决定哪些字段真正参与分组。

// 假设我们有一个方法来决定是否包含某个字段
Map<Object, List<StockDTO>> groupedResult = stockDTOS.stream().collect(Collectors.groupingBy(stock -> {// 创建一个复合键,根据条件决定包含哪些字段List<Object> keyParts = new ArrayList<>();// 条件1:如果满足条件,则将category加入分组键if (shouldIncludeCategory(stock)) {keyParts.add(stock.getCategory());}// 条件2:如果满足条件,则将date加入分组键if (shouldIncludeDate(stock)) {keyParts.add(stock.getDate());}// 条件3:如果满足条件,则将status加入分组键if (shouldIncludeStatus(stock)) {keyParts.add(stock.getStatus());}// 返回复合键return keyParts;}));

在上述代码中,通过shouldIncludeCategory、shouldIncludeDate、shouldIncludeStatus等方法判断条件,动态地将符合条件的字段添加到keyParts列表中,最终将该列表作为分组的键。这种方式直观易懂,适合逻辑相对简单的场景。但需要注意的是,由于列表作为键在进行哈希计算和比较时效率较低,在数据量较大时可能会影响性能。

二、使用 Map 作为复合键​

利用Map来构建复合键,能够以键值对的形式更加灵活地表示分组条件。

Map<Map<String, Object>, List<StockDTO>> groupedResult = stockDTOS.stream().collect(Collectors.groupingBy(stock -> {Map<String, Object> keyMap = new HashMap<>();// 根据条件添加字段到键映射中if (stock.getQuantity() > 100) {keyMap.put("category", stock.getCategory());}if (stock.getDate().isAfter(LocalDate.now().minusDays(7))) {keyMap.put("date", stock.getDate());}return keyMap;}));

此方法中,根据不同的条件,将相应的字段及其值以键值对的形式存入keyMap,再将keyMap作为分组的依据。这种方式相比使用列表作为复合键,在数据结构上更加灵活,能够清晰地表示每个字段及其条件关系。不过,Map作为键同样存在哈希计算和比较复杂的问题,并且在处理键的相等性判断时需要格外小心,因为Map的默认比较逻辑可能不符合实际需求,通常需要自定义equals和hashCode方法。​

三、使用枚举或常量表示字段选择​

通过定义枚举或常量来表示可选择的字段,能够使代码的可读性和可维护性得到提升。

// 定义字段选择枚举
enum GroupingField {CATEGORY, DATE, STATUS
}// 创建一个函数来决定每个字段是否应该参与分组
Map<Set<GroupingField>, List<StockDTO>> groupedResult = stockDTOS.stream().collect(Collectors.groupingBy(stock -> {Set<GroupingField> selectedFields = EnumSet.noneOf(GroupingField.class);if (stock.getPrice() > 100) {selectedFields.add(GroupingField.CATEGORY);}if (stock.getQuantity() < 50) {selectedFields.add(GroupingField.DATE);}return selectedFields;}));

在这种实现方式下,通过枚举GroupingField定义了所有可能参与分组的字段。在分组过程中,根据条件判断将相应的枚举值添加到selectedFields集合中,最终以该集合作为分组的键。这种方法的优势在于,当业务需求发生变化,需要新增或删除参与分组的字段时,只需在枚举中进行修改,代码的改动范围较小,易于维护。同时,由于枚举类型的特性,在进行条件判断和字段选择时,代码的逻辑更加清晰明了。​

四、使用自定义键对象​

创建一个自定义的键对象,将参与分组的字段作为该对象的属性,并通过重写equals和hashCode方法来实现自定义的键比较逻辑。

// 创建一个自定义键类
class GroupingKey {private final String category;private final LocalDate date;private final String status;// 构造函数和getter方法@Overridepublic boolean equals(Object o) {// 实现equals方法}@Overridepublic int hashCode() {// 实现hashCode方法}
}// 使用自定义键进行分组
Map<GroupingKey, List<StockDTO>> groupedResult = stockDTOS.stream().collect(Collectors.groupingBy(stock -> {// 根据条件创建键对象return new GroupingKey(shouldIncludeCategory(stock) ? stock.getCategory() : null,shouldIncludeDate(stock) ? stock.getDate() : null,shouldIncludeStatus(stock) ? stock.getStatus() : null);}));

自定义键对象的方式将参与分组的字段封装在一起,通过重写equals和hashCode方法,可以精确控制键的相等性判断和哈希值计算。这种方式在数据量大、对性能要求较高且需要复杂的键比较逻辑时非常适用,能够提供更稳定和高效的分组操作。但缺点是需要花费一定的精力去编写和维护自定义键类的相关代码。​

五、总结与选择建议​

上述介绍的四种方法各有优劣,在实际应用中,开发者需要根据具体的业务场景、数据规模以及对性能和代码可维护性的要求来选择合适的方式。如果业务逻辑简单,数据量较小,使用复合键并在其中应用条件逻辑或者使用Map作为复合键的方式能够快速实现需求;当需要清晰地表示字段选择,并且注重代码的可维护性时,使用枚举或常量表示字段选择的方式更为合适;而在对性能要求较高,且分组键的比较逻辑较为复杂的情况下,自定义键对象的方式则是更好的选择。通过灵活运用这些技巧,能够让我们在 Java 开发中更加高效地处理基于条件的动态分组需求,提升代码的质量和实用性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/85861.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/85861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AppBarLayout+ CoordinatorLayout,ViewPager2为什么不会覆盖AppBarLayout

<?xml version"1.0" encoding"utf-8"?> <layout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:tools"http://schemas.android.com/tools&quo…

【群体智能优化算法系列 】一 粒子群算法 (Particle Swarm Optimization, PSO)

【群体智能优化算法系列 】一 粒子算法 一&#xff1a;前言二&#xff1a;算法原理2.1 核心思想2.2 PSO核心公式​2.3 PSO算法流程图 三&#xff1a;python实现 二维Rastrigin函数 最低点检索例子参考 一&#xff1a;前言 粒子群算法是由Kennedy和Eberhart在1995年提出的一种基…

Jupyter notebook调试:设置断点运行

写了一段小代码&#xff0c;主要是用来测试一段序列的k均值聚类效果&#xff1b; 中间想到debug一下&#xff0c;但是想到自己似乎从来没有正式地接触过jupyter notebook中地debug&#xff0c;平时也只是多开几个cell&#xff0c;然后在其他cell中复制粘贴部分代码&#xff0c…

[12-2] BKP备份寄存器RTC实时时钟 江协科技学习笔记(14个知识点)

1 2 3 4 5 6 7 8 RTC是“Real-Time Clock”的缩写&#xff0c;中文意思是“实时时钟”。这是一种在电子设备中使用的时钟&#xff0c;它能够提供准确的时间信息&#xff0c;即使在设备断电的情况下也能继续运行&#xff0c;因为它通常由一个小型电池供电。RTC广泛应用于计算机…

优化给AI的“提问技巧”(提示工程),让大型语言模型(比如GPT)更好地扮演“心理治疗助手”的角色

优化给AI的“提问技巧”(提示工程),让大型语言模型(比如GPT)更好地扮演“心理治疗助手”的角色 尤其是在“问题解决疗法”(PST)中帮助 caregivers(家庭护理者)缓解焦虑、疲劳等心理症状。以下是核心内容的通俗解读: 一、研究背景:AI当心理医生靠谱吗? 现状:全球…

Java的lambda表达式应用

Lambda表达式是Java 8引入的一项强大特性&#xff0c;它允许以更加简洁的方式表示匿名函数。Lambda表达式不仅让代码更加简洁、清晰&#xff0c;而且为函数式编程提供了有力支持&#xff0c;从而提升了Java语言的表达能力。 本文主要讲解lambda应用stream处理集合的应用。 1、…

云原生/容器相关概念记录

文章目录 网络与虚拟化技术云平台与架构容器与编排容器网络方案性能优化与工具硬件与协议 网络与虚拟化技术 P4可编程网关 P4: Programming Protocol-independent Packet Processors一种基于P4语言的可编程网络设备&#xff0c;支持自定义数据包处理逻辑。P4可编程技术详解&am…

[C++] traits机制

文章目录 C之type_traitsis_floating_point<T> ..的使用std::enable_if<T>::type的使用std::remove_cv 如何自定义traits C之type_traits is_floating_point …的使用 一般在定义打印模板函数的时候&#xff0c;当我们用printf进行终端日志打印&#xff0c;需要根…

OpenCV 视频处理与保存

一、知识点 1、VideoCapture类 (1)、用于从视频文件、摄像机或图像序列中捕获视频帧。 (2)、构造函数 VideoCapture(const String & filename, int apiPreference CAP_ANY) a、filename可以是视频文件的名称(例如"video.avi")&#xff0c;可以是图…

【Leetcode】字符串之二进制求和、字符串相乘

文章目录 算法原理二进制求和题目链接题目描述解题思路代码 字符串相乘题目链接题目描述解题思路代码 算法原理 这两道题都是属于算法里一种经典题型&#xff1a;高精度加/减/乘/除法&#xff0c;需要我们模拟加/减/乘/除 列竖式运算。 二进制求和 题目链接 题目链接 题目描…

MongoDB:索引

目录 1、索引数据结构&#xff1a;B-树 2、索引类型 2.1 单字段索引 2.2 复合索引&#xff08;最重要&#xff01;&#xff09; 2.3 多键索引&#xff08;数组字段&#xff09; 2.4 地理空间索引 2.5 全文索引 2.6 哈希索引&#xff08;分片专用&#xff09; 2.7 TTL …

【大模型】Transformer架构完全解读:从“盲人摸象“到“通晓万物“的AI进化论

&#x1f916; Transformer架构完全解读&#xff1a;从"盲人摸象"到"通晓万物"的AI进化论 —— 一位大模型探索者的技术日记 ☕ 第一章&#xff1a;为什么说Transformer是AI界的"蒸汽机革命"&#xff1f; 1.1 从RNN到Transformer&#xff1a;…

JavaEE:使用JMeter进行接口并发测试

一、下载与安装&#xff1a; 1.下载apache-jmeter-5.6.3.zip&#xff1a; https://jmeter.apache.org/download_jmeter.cgi 2.解压到D:\Program Files\apache-jmeter-5.6.3目录 3.添加JDK环境配置到D:\Program Files\apache-jmeter-5.6.3\bin\jmeter.bat文件开头&#xff1…

【笔记】MSYS2 的 MinGW64 环境中正确安装 Python 相关环境管理工具 (Poetry、Virtualenv、Pipenv 和 UV)

MSYS2 环境配置与 Python 项目依赖管理笔记_msys更新python-CSDN博客 【技术笔记】MSYS2 指定 Python 版本安装方案_pacman -u 安装指定版本-CSDN博客 更多关于 MSYS2 开发环境的配置&#xff0c;请查看往期笔记。 简介 本笔记将记录我们在 MSYS2 的 MinGW64 环境中安装 Pytho…

ubuntu添加域名解析服务器地址

在 Ubuntu 中配置域名解析主要有两种方式&#xff1a;静态修改 /etc/hosts 文件 和 动态修改 DNS 解析服务器配置。以下是详细操作指南&#xff1a; 建议优选:二、永久方案&#xff1a;修改 DNS 解析服务&#xff08;推荐&#xff09;中的方法1 一、临时方案&#xff1a;修改…

通过 AIOps 、生成式 AI 和机器学习实现更智能的可观测性

支持 AIOps 的理由 人工智能运维&#xff08;AIOps&#xff09;是将人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;和分析技术应用于提升 IT 运维团队日常工作的过程。简单来说&#xff0c;AIOps 是软件系统通过 AI 和 ML 以及相关分析技术来简化和…

【DataWhale组队学习】AI办公实践与应用

AI办公-PPT制作 1. 使用大模型制作PPT的常见流程 使用大模型生成PPT的文稿将文稿的内容喂给可以直接生成PPT的大模型&#xff0c;生成PPT 2. 使用大模型生成PPT文稿 我们可以先使用上一章提过的那些大模型去生成一个PPT的文稿。那根据上一章的内容&#xff0c;我们想要去让…

人机融合智能 | 人智交互中的机器行为设计与管理

以人工智能为代表的科学技术正在深入地塑造和改变着人类的社会、文化和经济等,在“无所不在的算法与智能”的时代,了解智能机器的行为对于设计智能行为并使其造福于人类,对于智能机器的设计者、开发者和使用者,都具有重要意义。机器行为研究从学科交叉的视角,将智能机器行为置于…

langChainv0.3学习笔记(高级篇)

目录 工具创建工具从函数创建工具tool 装饰器结构化工具 从可运行对象创建工具子类化 BaseTool如何创建异步工具处理工具错误返回工具执行的artifact 使用内置工具和工具包自定义默认工具如何使用内置工具包 使用聊天模型调用工具定义工具模式Python 函数LangChain 工具Pydanti…

UiAutomator2 与 Appium 对比分析:安卓自动化测试框架的选择指南

目录 一、基础介绍UiAutomator2Appium 二、功能对比三、架构差异UiAutomator2 架构简图&#xff1a;Appium 架构简图&#xff1a; 四、使用场景分析五、优缺点总结UiAutomator2 优点&#xff1a;UiAutomator2 缺点&#xff1a;Appium 优点&#xff1a;Appium 缺点&#xff1a; …