0

0

Groovy中高效构建列表分组与嵌套父子结构

霞舞

霞舞

发布时间:2025-10-16 10:14:23

|

223人浏览过

|

来源于php中文网

原创

Groovy中高效构建列表分组与嵌套父子结构

本文详细介绍了如何在groovy中将扁平化的数据列表根据特定字段进行分组,并将其重构为具有父子关系的嵌套数据结构。通过利用groovy强大的`groupby`和`collect`方法,可以简洁高效地实现数据的分类、转换和格式化,从而满足复杂的数据组织需求。

在数据处理和转换中,我们经常需要将一个包含多个相同类型元素的扁平列表,按照某个共同的属性进行分组,并将其组织成一个更具层次感的结构,例如父子关系。这种结构化处理对于后续的数据展示、分析或API响应格式化至关重要。本文将以一个具体的示例,演示如何使用Groovy的集合操作,优雅地实现这一目标。

初始数据结构

假设我们有一个fakeList,其中包含多个表示不同保险覆盖类型的Map对象:

def fakeList = [
    [coverageType: 'health', amount: 9, expireDate: 2020], 
    [coverageType: 'insurance', amount: 10, expireDate: 2020], 
    [coverageType: 'health', amount: 9, expireDate: 2021],
]

我们的目标是将其转换为一个列表,其中每个元素代表一个唯一的coverageType(作为父级),并包含所有属于该coverageType的原始项(作为子级)。

目标数据结构

期望的输出格式如下所示,每个父级Map包含一个parent键和一个childs(或children)键,childs键的值是一个列表,包含了所有相关的子项:

[
    [parent:'health', childs:[
        [coverage:health, amount:9, expireDate:2020], 
        [coverage:health, amount:9, expireDate:2021]
    ]],
    [parent:'insurance', childs:[
        [coverage:insurance, amount:10, expireDate:2020]
    ]]
]

Groovy解决方案:groupBy与collect的组合应用

Groovy提供了强大的集合处理方法,其中groupBy和collect是实现此目标的理想工具

  1. groupBy方法:groupBy方法用于根据闭包的返回值对集合元素进行分组。它返回一个Map,其中键是闭包的返回值(即分组依据),值是包含所有属于该组的元素的列表。

    Gaga
    Gaga

    曹越团队开发的AI视频生成工具

    下载
    def groupedByCoverage = fakeList.groupBy { it.coverageType }
    // groupedByCoverage 的结果大致如下:
    // [
    //   health:[[coverageType:health, amount:9, expireDate:2020], [coverageType:health, amount:9, expireDate:2021]],
    //   insurance:[[coverageType:insurance, amount:10, expireDate:2020]]
    // ]
  2. collect方法:collect方法用于将集合中的每个元素转换为一个新的元素,并返回一个包含所有新元素的列表。在这里,我们将对groupBy的结果(一个Map)使用collect,将每个键值对(coverageType和其对应的列表)转换为我们所需的父子结构Map。

    def groupList = fakeList.groupBy { it.coverageType } // 首先按 coverageType 分组
                            .collect { coverageType, items -> // 对每个分组进行转换
        def map = [:] // 创建一个空的Map来构建父级结构
        map.'parent' = coverageType // 设置父级名称
        map.'childs' = items.collect { item -> // 遍历当前分组的子项,构建子项列表
            def childMap = [:] // 为每个子项创建一个Map
            childMap.'coverage' = coverageType // 添加子项的 coverage 类型
            childMap.'amount' = item.amount as String // 转换并添加 amount
            childMap.'expireDate' = item.expireDate as String // 转换并添加 expireDate
            childMap // 返回子项Map
        }
        map // 返回父级Map
    }

完整示例代码

将上述步骤整合,完整的Groovy代码如下:

import java.util.stream.Collectors

// 原始数据列表
def fakeList = [
    [coverageType: 'health', amount: 9, expireDate: 2020], 
    [coverageType: 'insurance', amount: 10, expireDate: 2020], 
    [coverageType: 'health', amount: 9, expireDate: 2021],
] 

// 使用 groupBy 和 collect 实现分组和结构化
def groupList = fakeList.groupBy { it.coverageType }
                        .collect { coverageType, items ->
        def parentMap = [:]
        parentMap.'parent' = coverageType 
        parentMap.'childs' = items.collect { item ->
            def childMap = [:]
            childMap.'coverage' = coverageType
            childMap.'amount' = item.amount as String // 注意:这里将数字转换为字符串
            childMap.'expireDate' = item.expireDate as String // 注意:这里将数字转换为字符串
            childMap
        }
        parentMap
}

// 打印结果
println groupList

运行结果

执行上述代码,将得到以下输出,这正是我们期望的父子结构:

[
    [parent:health, childs:[[coverage:health, amount:9, expireDate:2020], [coverage:health, amount:9, expireDate:2021]]],
    [parent:insurance, childs:[[coverage:insurance, amount:10, expireDate:2020]]]
]

注意事项与总结

  1. putAll的误用: 在原始问题中,用户尝试使用putAll来添加数组,但putAll通常用于将一个Map的所有键值对复制到另一个Map中,它会覆盖同名的键。对于列表的追加或嵌套,这种方法是不合适的。
  2. 类型转换: 在示例代码中,amount和expireDate字段被显式地转换为String类型(item.amount as String)。如果你的目标输出要求特定类型,务必进行相应的类型转换。
  3. Groovy的简洁性: groupBy和collect是Groovy集合操作的强大体现,它们允许用非常简洁和富有表达力的方式处理复杂的数据转换逻辑,避免了冗长的循环和条件判断。
  4. 灵活性: collect闭包内部可以根据需求进行任意复杂的转换逻辑。你可以选择性地包含或排除原始项的字段,甚至添加新的计算字段。

通过掌握groupBy和collect的组合使用,你将能够高效地在Groovy中处理各种数据分组和结构化任务,从而编写出更健壮、更易读的代码。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

381

2023.08.02

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

536

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

17

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

24

2026.01.06

go语言闭包相关教程大全
go语言闭包相关教程大全

本专题整合了go语言闭包相关数据,阅读专题下面的文章了解更多相关内容。

137

2025.07.29

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

75

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

60

2025.11.17

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

41

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.8万人学习

C# 教程
C# 教程

共94课时 | 7.5万人学习

Java 教程
Java 教程

共578课时 | 50.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号