Коллекция фильтров в Kotlin с существующим экземпляром java.util.Predicate - PullRequest
0 голосов
/ 18 февраля 2019

Я хочу отфильтровать коллекцию значений в Kotlin, используя экземпляр реализации java.util.Predicate, в основном примерно так:

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

Хотя это не компилируется.Следующие работы, это рекомендуемый способ сделать это?Чувствуется немного громоздким

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

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Чтобы ответить на него более прямо: да ... 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, вам не нужно адаптировать этот фильтр, а просто заменить / удалить оператор импорта нафункция расширения.

Функции расширения для простого преобразования 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), что может сделать рефакторинг в будущемнемного (IDEs помогают ;-)) сложнее.

0 голосов
/ 18 февраля 2019

Вы можете использовать ссылку на метод, которая неявно преобразуется в (T) -> Boolean и, таким образом, позволяет вызывать метод filter:

schedule.sport_events.filter(predicate::test)
...