高阶函数与 lambda 表达式
5.1 Lambda表达式和成员引用
5.1.1 Lambda简介:作为函数参数的代码块
button.setOnClickLisener(new OnClickListener(){
@Override
public void onClick(View view){
//点击后执行的动作
}
}button.setOnClickListener(/*点击后执行的动作*/)5.1.2 Lambda和集合
data class Person(val name:String,val age:Int)
fun findTheOldest(people:List<Person>){
var maxAge = 0
var theOldest:Person? = null
for (person in people){
if(person.age > maxAge){
maxAge = person.age
theOldest = person
}
}
println(theOldest)
}5.1.3 Lambda表达式的语法

和局部变量一样,如果lambda参数的类型可以被推倒出来,你就不需要显式地指定它。以这里的maxBy函数为例,其参数类型始终和集合的元素类型相同。编译器知道你是对一个Person对象的集合调用maxBy函数,所以它能推断lambda参数也会是Person类型。
如果当前上下文期望的是只有一个参数的Lambda切这个参数的类型可以推断出来,就会生成it这个名称。
5.1.4 在作用域中访问变量
和Java不一样,Kotlin允许在lambda内部访问非final变量甚至修改它们。从lambda内访问外部变量,我们称这些变量被lambda捕捉。
5.1.5 成员引用
kotlin和Java8一样,如果把函数转换成一个值,你就可以传递他。使用::元素安抚来转换。
这种表达式称为成员引用,它提供了简明语法,来创建一个调用单个方法或者访问单个属性的函数值。
成员引用和调用该函数的lambda具有一样的类型,可以互换使用:
还可以引用顶层函数
可以用构造方法引用存储或者延期执行创建类实例的动作。构造方法引用的形式是在双冒号后执行类名称:
还可以用同样的方式引用扩展函数:
5.2 集合的函数式API
5.2.1 基础:filter和map
filter和map函数形成了集合操作的基础,很多集合操作都是借助它们来表达的。
5.2.2 “all” “any” “count” 和 “find”:对集合应用判断式
all函数判断是否所有元素都满足判断式。
any函数判断是否至少存在一个匹配的元素。
count函数返回满足判断式元素的个数。
find函数找到满足判断的元素。
5.2.3 groupBy:把列表转换成分组的map
5.2.4 flatMap和flatten:处理嵌套集合中的元素
flatMap函数做了两件事情:首先根据作为实参给定的函数对集合中的每个元素做变换,然后把多个列表合并成一个列表。
5.3 惰性集合操作:序列
Kotlin标准库参考文档有说明,filter和map都会返回一个列表。这意味着上面例子中的链式调用会创建两个列表:一个保存filter函数的结果,另一个保存map函数的结果。如果源列表只有两个元素,这不是什么问题,但是如果有一百万个元素,调用就会变得十分低效。
为了提高效率,可以把操作变成使用序列,而不是直接使用。
Sequence接口的强大之处在于其操作的实现方式。序列中的元素求值是惰性的。因此可以使用序列更高效地对集合元素执行链式操作,而不需要创建额外的集合来保存过程中产生的中间结果。
可以调用扩展函数asSequence把任意集合转换成序列,调用toList来做反向的转换。
5.3.1 执行序列操作:中间和末端操作
中间操作始终是惰性的。
执行这段代码并不会在控制台上输出任何内容。这意味着map和filter变换被延期了,它们只有在获取结果的时候才会被应用。
末端操作触发执行了所有的延期计算。
�

5.3.2 创建序列
5.4 使用Java函数式接口
5.4.1 把lambda当做参数传递给Java方法
5.4.2 SAM构造方法:显式地把lambda转换成函数式接口
5.5 带接收者的lambda:“with”与“apply”
5.5.1 “with”函数
调用result实例上好几个不同的方法,而且每次调用都要重复result这个名称。
进一步重构alphabet函数,去掉额外的StringBuilder变量。
5.5.2 “apply”函数
apply函数几乎和with函数一模一样,唯一的区别是apply始终会返回作为实参传递给它的对象。
标准库函数buildString负责创建StringBuilder并调用toString。buildString的实参是一个带接收者的lambda,接收者就是StringBuilder。
最后更新于
这有帮助吗?