我想使用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谓词和/或将来计划将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帮助;-))更难。