1. 概述
Groovy 在 Java 的 Map 基础上进行了扩展,提供了更丰富的操作方法,比如 过滤、查找、排序 等功能。此外,Groovy 还支持多种简洁的方式来创建和操作 Map。
在本文中,我们将详细介绍 Groovy 中 Map 的使用方式,包括创建、添加、检索、删除、遍历、过滤、转换、分组和排序等常见操作。
2. 创建 Groovy Map
Groovy 提供了非常简洁的语法来创建 Map,使用 [k:v]
这种字面量形式,可以一行完成初始化。
创建空 Map
def emptyMap = [:]
创建带数据的 Map
def map = [name: "Jerry", age: 42, city: "New York"]
⚠️ 注意:Groovy 默认使用 LinkedHashMap
实现 Map,但你可以通过 as
运算符修改实现类型。
3. 添加元素
Groovy 支持多种方式添加键值对。
使用下标方式添加
def map = [name:"Jerry"]
map["age"] = 42
使用点号语法(类似 JS)
map.city = "New York"
✅ 推荐:Groovy 支持类似 Java Bean 的属性访问方式。
使用变量作为 key
def hobbyLiteral = "hobby"
def hobbyMap = [(hobbyLiteral): "Singing"]
map.putAll(hobbyMap)
assertTrue(hobbyMap.hobby == "Singing")
assertTrue(hobbyMap[hobbyLiteral] == "Singing")
4. 获取元素
获取 Map 中的值也有两种方式:
使用下标访问
def map = [name:"Jerry", age: 42, city: "New York", hobby:"Singing"]
assertTrue(map["name"] == "Jerry")
使用点号访问
assertTrue(map.name == "Jerry")
⚠️ 注意:如果 key 不存在,返回 null,不会抛异常。
5. 删除元素
Groovy 提供了多个删除方法,可以根据 key 删除,也可以根据条件批量删除。
删除单个 key
def map = [1:20, a:30, 2:42, 4:34, ba:67, 6:39, 7:49]
map.remove(2)
批量删除(minus)
def minusMap = map.minus([2:42, 4:34])
assertTrue(minusMap == [1:20, a:30, ba:67, 6:39, 7:49])
条件删除(removeAll)
minusMap.removeAll{it -> it.key instanceof String}
assertTrue(minusMap == [1:20, 6:39, 7:49])
保留符合条件的条目(retainAll)
minusMap.retainAll{it -> it.value % 2 == 0}
assertTrue(minusMap == [1:20])
6. 遍历 Map
Groovy 提供了 each()
和 eachWithIndex()
方法用于遍历 Map。
使用 each 遍历
map.each{entry -> println "$entry.key: $entry.value"}
使用 eachWithIndex 遍历(带索引)
map.eachWithIndex{entry, i -> println "$i $entry.key: $entry.value"}
单独获取 key 和 value
map.eachWithIndex{key, value, i -> println "$i $key: $value"}
7. 过滤 Map
Groovy 提供了多种过滤方法,如 find
, findAll
, grep
, every
, any
等。
示例数据
def map = [name:"Jerry", age: 42, city: "New York", hobby:"Singing"]
find - 找第一个符合条件的 Entry
assertTrue(map.find{it.value == "New York"}.key == "city")
findAll - 找出所有符合条件的 Entry
assertTrue(map.findAll{it.value == "New York"} == [city : "New York"])
grep - 返回 List 类型结果
map.grep{it.value == "New York"}.each{it -> assertTrue(it.key == "city" && it.value == "New York")}
every - 检查是否所有 Entry 都满足条件
assertTrue(map.every{it -> it.value instanceof String} == false)
any - 检查是否有 Entry 满足条件
assertTrue(map.any{it -> it.value instanceof String} == true)
8. 转换和收集 Map
Groovy 提供了 collect
和 collectEntries
方法,用于对 Map 的条目进行转换。
示例数据
def map = [
1: [name:"Jerry", age: 42, city: "New York"],
2: [name:"Long", age: 25, city: "New York"],
3: [name:"Dustin", age: 29, city: "New York"],
4: [name:"Dustin", age: 34, city: "New York"]
]
collect - 转换为 List
def names = map.collect{entry -> entry.value.name}
assertTrue(names == ["Jerry", "Long", "Dustin", "Dustin"])
collect - 指定集合类型(如 HashSet)
def uniqueNames = map.collect([] as HashSet){entry -> entry.value.name}
assertTrue(uniqueNames == ["Jerry", "Long", "Dustin"] as Set)
collectEntries - 转换为新 Map
def idNames = map.collectEntries{key, value -> [key, value.name]}
assertTrue(idNames == [1:"Jerry", 2:"Long", 3:"Dustin", 4:"Dustin"])
组合使用 find + collect
def below30Names = map.findAll{it.value.age < 30}.collect{key, value -> value.name}
assertTrue(below30Names == ["Long", "Dustin"])
9. 分组 Map
Groovy 提供了 groupBy
和 subMap
方法用于对 Map 进行分组。
groupBy - 按条件分组
def map = [1:20, 2: 40, 3: 11, 4: 93]
def subMap = map.groupBy{it.value % 2}
assertTrue(subMap == [0:[1:20, 2:40], 1:[3:11, 4:93]])
subMap - 按 key 指定子集
def keySubMap = map.subMap([1,2])
assertTrue(keySubMap == [1:20, 2:40])
10. 排序 Map
Groovy 提供了 sort()
方法,可用于根据 key、value 或两者排序。
示例数据
def map = [ab:20, a: 40, cb: 11, ba: 93]
默认排序(按 key 自然排序)
def naturallyOrderedMap = map.sort()
assertTrue([a:40, ab:20, ba:93, cb:11] == naturallyOrderedMap)
自定义比较器排序
def compSortedMap = map.sort({k1, k2 -> k1 <=> k2} as Comparator)
assertTrue([a:40, ab:20, ba:93, cb:11] == compSortedMap)
按 value 排序
def cloSortedMap = map.sort({it1, it2 -> it1.value <=> it2.value})
assertTrue([cb:11, ab:20, a:40, ba:93] == cloSortedMap)
11. 总结
本文介绍了 Groovy 中 Map 的多种操作方式,包括:
- 创建、添加、获取、删除
- 遍历、过滤、转换
- 分组、排序等高级操作
这些方法大大简化了我们在日常开发中对 Map 的处理,让代码更简洁、可读性更强。
如需完整示例代码,欢迎查看 GitHub 项目。