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

问题描述 投票:2回答:2

我想使用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) }
java kotlin filter collections predicate
2个回答
4
投票

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

schedule.sport_events.filter(predicate::test)

0
投票

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

如果你必须更频繁地处理Java谓词和/或将来计划将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然后您不需要调整该过滤器,只需将import语句替换/删除到扩展函数即可。

扩展函数只是将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帮助;-))更难。

© www.soinside.com 2019 - 2024. All rights reserved.