如何优雅实现两个Kotlin列表的元素全组合?
更优雅的Kotlin列表元素组合实现方式
当然有!嵌套forEach虽然能完成任务,但写起来繁琐,还得手动维护结果集合,确实不够优雅。Kotlin标准库提供了几个更简洁清晰的方案,让代码可读性拉满:
方案一:flatMap + map(最通用)
这是处理两个集合组合最常用的方式,代码简洁且兼容性好,不需要依赖特定Kotlin版本:
val ints = listOf(0, 1, 2) val strings = listOf("a", "b", "c") val combinations = ints.flatMap { num -> strings.map { str -> "$num$str" } } // 输出结果:[0a, 1a, 2a, 0b, 1b, 2b, 0c, 1c, 2c]
原理很简单:
flatMap会遍历ints中的每个元素,对每个元素执行后面的lambda- 对每个数字
num,用map把strings里的每个字符串str和num拼接成新字符串,得到一个临时小列表 - 最后
flatMap会把所有临时小列表“展平”成一个大列表,省去了手动收集结果的麻烦
方案二:用cartesianProduct(语义化拉满)
如果你用的是Kotlin 1.6及以上版本,标准库提供了cartesianProduct扩展函数,直接生成两个集合的笛卡尔积,代码更直观:
val combinations = ints.cartesianProduct(strings).map { (num, str) -> "$num$str" }
cartesianProduct会直接返回两个集合所有元素的配对元组(比如Pair(0, "a")),我们只需要把元组里的两个元素拼接起来即可。这个写法一看就知道是在求集合的笛卡尔积,语义非常清晰。
方案三:序列Sequence(大数据量友好)
如果你的列表元素很多,担心内存占用问题,可以用Sequence来实现延迟计算:
val combinations = ints.asSequence() .flatMap { num -> strings.asSequence().map { str -> "$num$str" } } .toList()
序列不会一次性把所有组合都加载到内存里,而是按需生成元素,在处理超大集合时能有效降低内存开销。
总结
- 日常场景优先选
flatMap + map,兼容性好且代码简洁 - 追求语义化可以用
cartesianProduct(Kotlin 1.6+) - 处理大数据量记得用
Sequence优化内存
内容的提问来源于stack exchange,提问作者fweigl
相关产品推荐
相关产品推荐

