В настоящее время я пытаюсь сравнить лямбды Java с лямбдами Kotlin. Я считаю преимуществом то, что котлину не нужны функциональные интерфейсы для создания лямбда. Я думаю, что это немного отличается - получить обзор всех функциональных интерфейсов в Java, чтобы очень хорошо использовать лямбды и манипуляции с коллекциями.
Но во время исследования я обнаружил и отрицательный момент. Я думаю, что у Predicate в Java есть функция по умолчанию, которая позволяет комбинировать некоторые лямбды.
Итак, вы можете сделать что-то вроде этого на Java:
final Predicate<Person> isAdult = person -> person.getAge() >= 18;
final Predicate<Person> isMale = person -> person.getGender() == Gender.MALE;
// Combine
final Predicate<Person> isAdultAndMale = isAdult.and(isMale);
Я думаю, что сейчас есть эквивалент в Котлине. Я прочитал в Head first Kotlin, что есть функция комбинирования. Но на детской площадке Kotlin это не работает. Так что я получаю функцию расширения. Соответственно с двумя функциями расширения. Один для двух лямбд, а другой для более чем двух лямбд и с вараргами.
enum class Gender{MALE, FEMALE}
enum class EyeColor{BLUE, GREEN}
data class Person(
var name: String,
var age: Int,
var gender: Gender,
var eyeColor: EyeColor
)
fun List<Person>.combineTwoLambdas(firstLambda: (Person) -> Boolean, secondLambda: (Person) -> Boolean): List<Person> {
return this.filter(firstLambda).filter(secondLambda)
}
fun List<Person>.combineMoreLambdas(vararg personFilters: (Person) -> Boolean): List<Person> {
var myPersons = listOf<Person>()
personFilters.forEach {
myPersons = this.filter(it)
}
return myPersons
}
typealias PredicatePersons = (Person) -> Boolean
fun main() {
val persons = listOf(
Person("Susi", 20, Gender.FEMALE, EyeColor.BLUE),
Person("Ralf", 19, Gender.MALE, EyeColor.BLUE),
Person("Michael", 20, Gender.MALE, EyeColor.GREEN))
val isAdult: (Person) -> Boolean = {person -> person.age >= 18}
val isMale: (Person) -> Boolean = {it.gender == Gender.MALE}
val hasGreenEyes: PredicatePersons = {it.eyeColor == EyeColor.GREEN}
// combine two lambdas
val isAdultAndMale = persons.combineTwoLambdas(isAdult, isMale)
// combine more than two lambdas
val isAdultAndMaleAndHasGreenEyes = persons.combineMoreLambdas(isAdult, isAdult, hasGreenEyes)
print("combine all ${isAdultAndMaleAndHasGreenEyes}")
}
Как-то проще связать несколько лямбд? Спасибо.
ОБНОВЛЕНИЕ
Вот обновление. Спасибо @Sweeper
val isAdultAndMale: (Person) -> Boolean = {isAdult(it) && isMale(it)}
// with alias
val isAdultAndMale: PredicatePersons = {isAdult(it) && isMale(it)}
{ predictate1(it) && predicate2(it) }
) достаточно лаконично, вам не кажется? В отличие от Java, где вам нужно.apply
повсюду. - person Sweeper   schedule 09.04.2020