如何按名称合并列表中的多个User对象?
如何按名称合并Groovy列表中的User对象?
当然可以实现!在Groovy里,借助它强大的集合API和闭包特性,你完全可以轻松完成按名称合并User对象的需求,甚至能封装出类似你设想的mergeBy方法来简化操作。
核心思路
我们需要先把列表中的User按name分组,然后对每个分组内的User对象进行属性合并——将非null的属性整合到一个新的User实例中,最终得到去重且属性完整的用户列表。
具体实现
首先保留你原有的User类和methodTest方法,然后添加合并逻辑:
基础实现方式
直接使用Groovy原生的集合方法完成合并:
class User { String name Integer age Integer score } def methodTest() { User a = new User().with{ it.name = "JACK"; it.age = 20 } User b = new User().with{ it.name = "JACK"; it.score = 50 } User c = new User().with{ it.name = "TONY"; it.age = 25 } User d = new User().with{ it.name = "TONY"; it.score = 30 } List userList = [a, b, c, d] // Groovy里可以直接用列表字面量,更简洁 // 核心合并逻辑 def mergedUsers = userList.groupBy { it.name }.collect { name, users -> def mergedUser = new User(name: name) // 先初始化name(分组键,必然存在) users.each { user -> // 只合并非null的属性 if (user.age != null) mergedUser.age = user.age if (user.score != null) mergedUser.score = user.score } mergedUser } // 输出验证结果 println mergedUsers // 结果:[User(name:JACK, age:20, score:50), User(name:TONY, age:25, score:30)] } methodTest()
封装成通用的mergeBy方法
如果你想实现类似userList.mergeBy(it.name)的简洁调用,可以给List添加一个扩展方法,让它更通用:
class User { String name Integer age Integer score } // 给List添加扩展方法,支持按指定属性合并对象 List.metaClass.mergeBy = { Closure groupingClosure -> delegate.groupBy(groupingClosure).collect { key, items -> // 创建当前类型的新实例 def merged = items[0].getClass().newInstance() items.each { item -> // 遍历所有属性,排除class属性,只合并非null值 item.properties.each { propName, propValue -> if (propName != 'class' && propValue != null) { merged[propName] = propValue } } } merged } } def methodTest() { User a = new User().with{ it.name = "JACK"; it.age = 20 } User b = new User().with{ it.name = "JACK"; it.score = 50 } User c = new User().with{ it.name = "TONY"; it.age = 25 } User d = new User().with{ it.name = "TONY"; it.score = 30 } List userList = [a, b, c, d] // 简洁调用合并方法 def mergedUsers = userList.mergeBy { it.name } println mergedUsers // 结果:[User(name:JACK, age:20, score:50), User(name:TONY, age:25, score:30)] } methodTest()
注意事项
- 如果同一分组内的多个对象有重复的非null属性(比如两个同名User都设置了
age),后面的对象属性会覆盖前面的。如果需要其他合并策略(比如取平均值、保留第一个值),可以修改collect中的合并逻辑。 - 扩展方法是Groovy的特性,如果你在Java环境中调用,可能需要调整实现方式,但在纯Groovy项目中可以直接使用。
内容的提问来源于stack exchange,提问作者Gustavo Trevisani
相关产品推荐
相关产品推荐

