使用现有 java.util.Predicate 个实例在 Kotlin 中过滤集合

Filter collection in Kotlin with existing java.util.Predicate instance

我想使用 java.util.Predicate 实现的实例过滤 Kotlin 中的值集合,基本上是这样的:

val predicate = JsQueryPredicate<SportEvent>(query)
schedule.sport_events.filter(predicate)

虽然这不会编译。以下作品,这是推荐的方法吗?感觉有点麻烦

val predicate = JsQueryPredicate<SportEvent>(query)
schedule.sport_events.filter { predicate.test(it) }

您可以使用方法引用,它会隐式转换为 (T) -> Boolean,从而允许您调用 filter 方法:

schedule.sport_events.filter(predicate::test)

更直接地回答:是的...predicate.test(it) 或几乎等效的方法参考 predicate::test 是要走的路...除了...

如果您必须更频繁地处理 Java 谓词 and/or,计划将 Java 函数类型(例如 Predicate)重构为 Kotlin 函数类型将来,您可能还想添加适当的扩展功能,例如:

fun <T> Iterable<T>.filter(predicate: Predicate<T>) = filter { predicate.test(it) }

然后使用以下用法:

val javaPredicate : Predicate<String> = Predicate { it == "hello" }
listOf("hello", "world")
        .filter(javaPredicate)

如果您以后将 Predicate 替换为,例如(T) -> Boolean 然后您不需要调整该过滤器,而只需 replace/remove 扩展函数的导入语句。

仅将 Predicate 转换为适当的 Kotlin 函数类型的扩展函数也是可能的,但在未来的重构中可能对您帮助不大:

operator fun <T> Predicate<T>.invoke() : (T) -> Boolean = ::test
fun <T> Predicate<T>.transform() : (T) -> Boolean = ::test

使用示例:

val javaPredicate : Predicate<String> = Predicate { it == "hello" }

// variant with Predicate.invoke:
listOf("hello", "world")
    .filter(javaPredicate())

// variant using Predicate.transform()
listOf("hello", "world")
    .filter(javaPredicate.transform())

所以我建议您使用重载的 filter 方法,以防您计划重构或坚持使用 filter { predicate.test(it) }/filter(predicate::test),这可能会使未来的重构有点( IDE 帮助 ;-)) 更难。