java - 如何在 Kotlin 中组合 lambda
问题描述
我目前正在尝试将 Java lambdas 与 Kotlin lambdas 进行比较。我认为 kotlin 不需要函数式接口来创建 lambda 是一个优势。我认为了解 Java 中的所有功能接口以很好地使用 lambda 和集合操作有点不同。
但我在研究过程中也发现了一个负面因素。我认为 Java 中的 Predicate 有一个默认函数,它可以让你组合一些 lambdas。
所以你可以在 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 现在有等价物。我在 Head first Kotlin 中读到有一个 combine 函数。但它在 Kotlin 操场上不起作用。所以我最终得到了一个扩展功能。分别具有两个扩展功能。一个用于两个 lambda,另一个用于两个以上的 lambda 和可变参数。
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}")
}
链接多个 lambda 是否更容易?谢谢。
更新
这是一个更新。感谢@Sweeper
val isAdultAndMale: (Person) -> Boolean = {isAdult(it) && isMale(it)}
// with alias
val isAdultAndMale: PredicatePersons = {isAdult(it) && isMale(it)}
解决方案
您可以定义and
和的等价物or
作为扩展函数:
fun <T> ((T) -> Boolean).and(arg: (T) -> Boolean): (T) -> Boolean = { this(it) && arg(it) }
fun <T> ((T) -> Boolean).or(arg: (T) -> Boolean): (T) -> Boolean = { this(it) || arg(it) }
...
val isAdultAndMale = isAdult.and(isMale)
推荐阅读
- python - Pandas 创建一个框架,其条目是应用于其他 DataFrame 的相应条目的函数的值
- wordpress - Wordpress,限制页面和内容访问具有特定角色的登录用户
- django - 如何在 django 令牌身份验证中检查用户是否已登录?
- loops - 带有用户输入的小循环 unix
- php - php mongodb 验证表单密码
- sql - 左连接命令未显示所有结果
- react-native - 处理 useEffect
- javascript - 将 Google Tag Manager 与 Google Analytics 结合使用来跟踪 Chrome 扩展程序 (2020)
- list - 如何将列表添加到地图
> 动态 - android - Recyclerview 项目 OnTouchListener