Kotlin中如何基于Lambda/谓词实现两个列表的自定义交集?
问题解答
核心结论
Kotlin标准库没有提供跨不同类型集合、支持自定义匹配条件的intersect重载方法。标准库原生的intersect仅针对同类型集合,且依赖元素的equals和hashCode判断相等性,无法满足你跨类型自定义匹配的需求。
现有实现分析
你自行编写的扩展方法逻辑是正确的,能实现预期功能:
fun<T, U> List<T>.intersect(list2: List<U>, p: (a: T, b: U) -> Boolean): List<T> = this.filter { list2.any { other -> p(it, other) } }
但需注意:当bars集合数据量较大时,该实现的时间复杂度为O(m*n)(m为foos长度,n为bars长度),性能会随数据量增长明显下降。
优化建议
如果你的匹配逻辑始终是基于「提取两个集合元素的键进行相等判断」(比如你的场景是Foo.id和Bar.fId匹配),可以优化扩展方法,先将bars的键提取到Set中,把时间复杂度降到O(m+n):
fun<T, U> List<T>.intersectByKey( other: List<U>, keyExtractor: (T) -> Any, otherKeyExtractor: (U) -> Any ): List<T> { val otherKeys = other.map(otherKeyExtractor).toSet() return this.filter { keyExtractor(it) in otherKeys } }
使用方式更简洁直观:
val actual = foos.intersectByKey(bars, { it.id }, { it.fId })
总结
如果你的匹配逻辑是基于键的,优先使用优化后的键匹配版本;如果需要完全自定义任意匹配规则,你最初的扩展方法是合理的选择,标准库没有对应的替代方法,可以放心使用。
内容的提问来源于stack exchange,提问作者user2084865
相关产品推荐
相关产品推荐

