Kotlin实现列表对象排除id字段后按其余属性分组
问题原因
现有代码直接使用groupBy { it }分组时,Kotlin data class的结构相等判断会覆盖所有声明字段,而业务场景下id是唯一值,会导致每个Product实例的相等判断结果都为false,无法按其他属性完成聚合。
最优实现方案
利用Kotlin data class自带的copy方法,分组时将所有实例的id统一设置为固定占位值(比如0)作为分组键,不需要手动枚举所有非id字段,天然适配20+字段的复杂模型,也能自动支持后续字段增减;同时Kotlin对List、嵌套data class默认做深度结构相等比较,完全满足嵌套对象、列表字段的一致性判断需求。
注意:
copy是浅拷贝,不会额外深度复制嵌套列表、对象,性能开销极低;分组后不要用分组键作为返回的Product实例(分组键的id是占位值),直接取分组内第一个原始Product对象即可保留真实业务数据。
修改后的核心代码:
// 可以删掉自定义的getTotalQuantity方法,直接用Kotlin内置的sumOf扩展 val groupedProducts = products // 核心逻辑:分组时统一id为固定值,忽略原始id的差异 .groupBy { it.copy(id = 0) } .map { (_, groupList) -> val isGroup = groupList.size > 1 GroupedProduct( product = groupList.first(), count = groupList.size, totalQuantity = groupList.sumOf { it.quantity }, isGroup = isGroup ) }
效果验证
使用id各不相同的测试数据:
var products = listOf( Product(1, "p1", 10, 2, listOf(SubModel("a", "1")), listOf("a")), Product(2, "p1", 10, 2, listOf(SubModel("a", "1")), listOf("a")), Product(3, "p1", 10, 2, listOf(SubModel("b", "2")), listOf("a")), Product(4, "p2", 12, 1, listOf(SubModel("a", "1")), listOf("a")), Product(5, "p3", 12, 1, listOf(SubModel("a", "1")), listOf("a")), )
运行后输出完全符合预期:
GroupedProduct(product=Product(id=1, name=p1, price=10, quantity=2, subModels=[SubModel(name=a, value=1)], values=[a]), count=2, totalQuantity=4, isGroup=true) GroupedProduct(product=Product(id=3, name=p1, price=10, quantity=2, subModels=[SubModel(name=b, value=2)], values=[a]), count=1, totalQuantity=2, isGroup=false) GroupedProduct(product=Product(id=4, name=p2, price=12, quantity=1, subModels=[SubModel(name=a, value=1)], values=[a]), count=1, totalQuantity=1, isGroup=false) GroupedProduct(product=Product(id=5, name=p3, price=12, quantity=1, subModels=[SubModel(name=a, value=1)], values=[a]), count=1, totalQuantity=1, isGroup=false)
不推荐的备选方案
你也可以手动枚举所有非id字段构造元组作为分组键,比如:
.groupBy { tupleOf( it.name, it.price, it.quantity, it.subModels, it.values // 所有新增字段都需要手动补充到这里 ) }
这种方式维护成本极高,Product字段增减时必须同步修改分组键逻辑,很容易因为漏写字段导致分组错误,不适合字段多的业务模型。
内容的提问来源于stack exchange,提问作者Celil Uysal
相关产品推荐
相关产品推荐

