使用reduce实现多列表交集函数出错,求原因及正确写法
问题分析
你的代码存在两个核心错误:
acc.toMutableSet()创建了新集合,未修改原acc:你对这个新集合执行retainAll操作,但原acc是不可变List,根本不会被改变。apply返回原对象:acc.apply { ... }最终返回的还是最初的acc,所以reduce每次迭代都把第一个列表当作累积值返回,自然得不到正确的交集。
正确的Reduce实现
用reduce实现时,每次迭代需要计算当前累积列表与当前列表的交集,并将这个交集作为新的累积值返回,而非操作原累积对象:
fun <T> List<List<T>>.intersection(): List<T> { return this.reduce { currentIntersection, nextList -> currentIntersection.toSet() .intersect(nextList.toSet()) .toList() } }
代码说明
- 每次迭代中,先把当前累积的交集列表转成Set(利用Set的高效交集操作),和下一个列表的Set求交集,再转回List作为新的累积值。
- 针对你传入的测试用例,第一次迭代会计算
[12,321]和[4,35,4]的交集(空列表),后续迭代都是空列表与其他列表求交集,最终返回空列表,符合预期。
额外优化(更高效)
如果追求性能,可以先将第一个列表转为可变Set,再依次和后续列表求交集,避免多次List与Set的转换:
fun <T> List<List<T>>.intersection(): List<T> { if (isEmpty()) return emptyList() val intersectionSet = first().toMutableSet() drop(1).forEach { intersectionSet.retainAll(it) } return intersectionSet.toList() }
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

