Я сейчас пытаюсь сравнить Java лямбды с Kotlin лямбдами. Я думаю, что это преимущество в том, что kotlin не нужны функциональные интерфейсы для создания лямбды. Я думаю, что немного по-другому взглянуть на все функциональные интерфейсы в Java, чтобы очень хорошо использовать лямбды и манипуляции с коллекциями.
Но я обнаружил и отрицательный момент в ходе своих исследований. Я думаю, что предикат в 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);
Я думаю, что теперь есть эквивалент в Kotlin. Сначала я прочитал в главе 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)}