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
英文地址,請注明出處:http://en.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; …