List 通过比较每种类型的值,从其他两个不同类型的列表中创建一个新列表

List 通过比较每种类型的值,从其他两个不同类型的列表中创建一个新列表,list,kotlin,filtering,List,Kotlin,Filtering,我有两个对象列表,它们都实现了一个接口,但在其他方面是不相关的。如何创建一个新的对象集合,其中只包含一个列表中与另一个列表中的值匹配的对象 显然,我可以使用for循环&手动执行此操作,但我想知道如何使用Kotlin的标准库集合过滤函数来执行此操作 下面是一个例子: interface Ids { val id: Int } data class A(override val id: Int, val name: String) : Ids data class B(override v

我有两个对象列表,它们都实现了一个接口,但在其他方面是不相关的。如何创建一个新的对象集合,其中只包含一个列表中与另一个列表中的值匹配的对象

显然,我可以使用for循环&手动执行此操作,但我想知道如何使用Kotlin的标准库集合过滤函数来执行此操作

下面是一个例子:

interface Ids
{
    val id: Int
}

data class A(override val id: Int, val name: String) : Ids
data class B(override val id: Int, val timestamp: Long) : Ids

fun main(args: Array<String>) {
    val a1 = A(1, "Steve")
    val a2 = A(2, "Ed")
    val aCol = listOf(a1, a2)

    val b2 = B(2, 12345)
    val b3 = B(3, 67890)
    val bCol = listOf(b2, b3)

    val matches = mutableListOf<B>()
    // This is where I'm stuck.
    // I want to filter bCol using objects from aCol as a filter.
    // The result should be that matches contains only a single object: b2
    // because bCol[0].id == aCol[1].id
    // I'm guessing I need to start with something like this:
    bCol.filterTo(matches) { ??? }
}
接口ID
{
val id:Int
}
数据类A(覆盖val id:Int,val名称:String):id
数据类B(覆盖val id:Int,val时间戳:Long):id
趣味主线(args:Array){
val a1=A(1,“Steve”)
val a2=A(2,“Ed”)
val aCol=列表(a1,a2)
valb2=B(212345)
val b3=B(367890)
val bCol=listOf(b2,b3)
val matches=mutableListOf()
//这就是我被困的地方。
//我想使用aCol中的对象作为过滤器来过滤bCol。
//结果应该是匹配项只包含一个对象:b2
//因为bCol[0].id==aCol[1].id
//我想我需要从这样的事情开始:
bCol.filterTo(匹配项){???}
}

一种简单的方法是在
bCol
中为每个
b
搜索具有相同id的对象:

bCol.filter { b -> aCol.any { a -> a.id == b.id } }
val aColIds = aCol.map { it.id }.toSet()
然而,如果你的列表足够大,这可能会变得太慢

为了使其更具可扩展性,您可以首先在
aCol
中构建一组所有ID:

bCol.filter { b -> aCol.any { a -> a.id == b.id } }
val aColIds = aCol.map { it.id }.toSet()
然后使用
Set.contains
方法确定
b.id
是否在
aColIds
中:

bCol.filter { it.id in aColIds }
// or equivalent
bCol.filter { aColIds.contains(it.id) }

我最终得到了我想要的:
bCol.filterTo(matches){aCol.map{it.id}.contains(it.id)}
。与您的答案相比,您知道这会如何影响性能吗?在这个特殊的例子中,我永远不会有一个非常大的数据集(@JordanBondo这比第一种方法更慢,因为
aCol.map
是为
bCol
中的每个项目调用的,然后结果被丢弃。因此它不仅增加了计算复杂度,而且还带来了显著的内存开销。对于其他遇到此问题的人,我用两个大(1mil)进行了一些测试和小型(256)数据集,发现尽管@Ilya的解决方案确实比我的快得多,但使用
filterTo
而不是
filter
也有显著的性能改进。