如何使用Kotlin流移除Map中重复name的条目并保留最小id的条目
处理Kotlin Map,移除name重复条目并保留id最小项
给定一个Map<String, MyObject>,我们需要移除值中name重复的条目,仅保留每个name对应id最小的那个条目。以下是两种实现方式:
方式一:使用Kotlin原生集合操作(推荐)
Kotlin标准库提供的集合扩展函数更贴合语法习惯,代码简洁易读:
data class MyObject(val id: Int, val name: String) fun main() { val inputMap = mapOf( "first" to MyObject(1, "Alice"), "second" to MyObject(2, "Bob"), "third" to MyObject(3, "Alice") ) val resultMap = inputMap.entries // 按MyObject的name字段分组,同一name的条目归为一组 .groupBy { it.value.name } // 每组内筛选出id最小的条目 .mapValues { (_, entries) -> entries.minBy { it.value.id } } // 提取保留的条目,重新构建目标Map .values.associateBy({ it.key }, { it.value }) println(resultMap) // 输出:{first=MyObject(id=1, name=Alice), second=MyObject(id=2, name=Bob)} }
步骤拆解
- 分组:
groupBy { it.value.name }将所有条目按MyObject的name字段分组,得到Map<String, List<Map.Entry<String, MyObject>>>结构。 - 筛选最小id条目:
mapValues遍历每个分组,通过minBy { it.value.id }找出分组内id最小的条目。 - 重构Map:提取所有保留的条目,用
associateBy重新构建为原结构的Map<String, MyObject>。
方式二:使用Java Stream API
如果偏好使用Stream流操作,可通过Collectors.toMap实现:
import java.util.stream.Collectors data class MyObject(val id: Int, val name: String) fun main() { val inputMap = mapOf( "first" to MyObject(1, "Alice"), "second" to MyObject(2, "Bob"), "third" to MyObject(3, "Alice") ) val resultMap = inputMap.entries .stream() // 按name分组,重复name时保留id更小的条目 .collect(Collectors.toMap( { it.value.name }, { it }, { existing, new -> if (existing.value.id < new.value.id) existing else new } )) .values.associateBy({ it.key }, { it.value }) println(resultMap) }
步骤拆解
- Stream收集:
Collectors.toMap的三个参数分别为:分组键(name)、要收集的值(原条目)、冲突解决逻辑(比较id保留更小的条目)。 - 重构Map:最后将分组后的条目集合转换为目标Map结构。
两种方式均能得到预期结果,Kotlin原生集合操作更适合日常开发场景。
内容的提问来源于stack exchange,提问作者Hamid Ghasemi
相关产品推荐
相关产品推荐

