Skip to content

在前面的内容中我们曾用匿名内部类的形式实现了按钮button的点击事件监听,其实还有一种更加简单的方式,就是使用lambda表达式. lambda就是允许把函数当作值来对待,可以直接传递函数,而不需要声明一个类再传递这个类的实例

Lambda表达式的语法

fun main(args: Array<String>) {
    val sum = { x: Int, y: Int -> x + y }
    println(sum(1, 2))
}

Lambda表达式使用花括号包围起来, 参数并没有使用括号包起来,使用 -> 把参数和函数体隔开

继续来看个例子, 我们有个Person集合, 需要从集合中找出年龄最大的

data class Person(val name: String, val age: Int)

fun main(args: Array<String>) {
    val persons = listOf(Person("Herman", 20), Person("Pitt", 35), Person("Taomm", 20))
    println(persons.maxByOrNull( { person: Person -> person.age }))
}

maxByOrNull: Kotlin对集合的扩展函数, 接受lambda表达式;

Kotlin的语法约定:

  • 当lambda表达式是函数的最后一个函数允许放到括号的外面
persons.maxByOrNull() { person: Person -> person.age }
  • 当lambda表达式是函数的唯一参数时,可以去掉空括号
persons.maxByOrNull { person: Person -> person.age }
  • 由于Kotlin的编译器能够根据集合元素类型推导出参数类型, 所以可以进一步简化
persons.maxByOrNull { person -> person.age }
  • 如果当前的lambda只有一个参数并且参数的类型能够推到出来,kotlin就会默认生成一个参数名it, 所以进一步简化
persons.maxByOrNull { it.age }
  • 上面的例子已经比较简洁了, 但其实还有另一种写法
persons.maxByOrNull(Person::age)

若你使用参数来存储lambda表达式,那么就必须要指定类型, 比如

val getAge = { p: Person -> p.age }
persons.maxByOrNull(getAge)

Kotlin中lambda表达式限制访问final变量, 可以在lambda表达式中修改这些变量

集合的函数式API

Koltin集合的函数式操作和Java的基本相同, 可以参考以前的文章 从零开始学习java8stream看这篇就够了

序列

在集合的函数式中,我们通常会使用链式调用, 比如map, filter, 每次在调用这函数的Koltin都会去创建中间集合来存储临时结果,为了提高效率可以把操作变成序列,而不直接使用集合; 比如获取所有Person的name

val names = persons.asSequence().map(Person::name).toList()

序列的操作分为中间操作和末端操作, 其中中间操作是惰性的, 把上面的例子修改下:

val names = persons.asSequence().map { p ->
    println(p.name)
    p.name
}

执行这段代码后我们会发现不会打印出任何内容,这是由于中间操作是惰性的,不会去执行; 如果我们把asSequence去掉就可以打印出来.

with、apply函数

在实际的项目中,经常会对同一个对象进行多次操作,这时候可以使用with函数,可以不用反复把对象名写出来.

val name = with(Person("Herman", 20)) {
    println(name)
    println(this.age)
    name
}
println(name)

在lambda表达式的作用域中,可以直接使用this指针引用Person对象; with函数的返回结果就是lambda表达式的最后一行表达式; 有时候我们需要返回接收对象本身,上面的例子可以直接把name替换成this , 还可以使用apply函数

val person = Person("Herman", 20).apply {
    println(name)
    println(this.age)
}
println(person)

原文链接: http://herman7z.site