Groovy中LinkedHashMap添加至列表及groupBy方法使用问题排查
解决Groovy中LinkedHashMap列表初始化与groupBy的问题
我来帮你梳理下三个版本代码的问题,再给出完全符合你需求的正确实现:
各版本报错原因拆解
Version1 无法运行的原因
你只声明了泛型列表变量List<LinkedHashMap> listOfRecords,但没有创建实际的列表实例——此时这个变量是null。调用add()方法时自然会触发空指针异常,这就是脚本报错的根源。
Version3 报错的双重原因
- 和Version1一样,
List listOfRecords;只是声明了变量,没有初始化列表实例,调用add()时会直接报错; - 没有指定泛型类型,在你的Planning服务器这种开启静态类型检查的环境中,列表元素会被默认识别为
Object类型,所以groupBy { it.cluster }里访问it.cluster时,编译器会提示Object没有cluster属性。
Version2 能运行但不符合需求
这个版本通过List listOfRecords=[a]初始化了列表,所以能正常调用add(),但你不想在声明时就添加元素,所以需要调整初始化方式。
符合需求的正确实现
我们需要先初始化空的泛型列表实例,同时明确泛型类型以满足静态类型检查,之后再逐个添加元素:
// 声明并初始化空的泛型列表 List<LinkedHashMap<String, Object>> listOfRecords = [] LinkedHashMap<String, Object> a = [product: 'p1', cluster: 'c1', salesorg: 's1'] LinkedHashMap<String, Object> b = [product: 'p2', cluster: 'c2', salesorg: 's2'] LinkedHashMap<String, Object> c = [product: 'p2', cluster: 'c3', salesorg: 's2'] // 逐个添加元素到空列表 listOfRecords.add(a) listOfRecords.add(b) listOfRecords.add(c) println("listOfRecords : "+listOfRecords) println("listOfRecords groupby : "+listOfRecords.groupBy { it.cluster })
关键细节说明
- 用
[]初始化空列表(Groovy中[]默认对应ArrayList实例),同时指定泛型List<LinkedHashMap<String, Object>>,这样静态类型检查器能明确识别列表元素是LinkedHashMap,访问it.cluster就不会报错; - 给
LinkedHashMap也指定泛型类型LinkedHashMap<String, Object>(键为字符串,值为任意类型),让类型声明更严谨,避免静态检查的警告; - 完全满足你"先创建空列表,再逐个添加元素"的需求。
可选简化写法
如果觉得逐个声明map变量太繁琐,也可以用更简洁的Groovy风格实现:
List<LinkedHashMap<String, Object>> listOfRecords = [] // 直接把字面量map转为LinkedHashMap后添加 listOfRecords.add([product: 'p1', cluster: 'c1', salesorg: 's1'] as LinkedHashMap) listOfRecords.add([product: 'p2', cluster: 'c2', salesorg: 's2'] as LinkedHashMap) listOfRecords.add([product: 'p2', cluster: 'c3', salesorg: 's2'] as LinkedHashMap) println("listOfRecords : "+listOfRecords) println("listOfRecords groupby : "+listOfRecords.groupBy { it.cluster })
或者用collect一步到位:
def listOfRecords = [ [product: 'p1', cluster: 'c1', salesorg: 's1'], [product: 'p2', cluster: 'c2', salesorg: 's2'], [product: 'p2', cluster: 'c3', salesorg: 's2'] ].collect { it as LinkedHashMap } println("listOfRecords : "+listOfRecords) println("listOfRecords groupby : "+listOfRecords.groupBy { it.cluster })
这个写法用collect把每个字面量map转换成LinkedHashMap,代码更简洁,同样能达成你的需求。
内容的提问来源于stack exchange,提问作者navi27
相关产品推荐
相关产品推荐

