本文正在参与「金石计划 . 分割6万现金大奖」

前言

前段时间在技术交流群里看一群大佬在说Kotlin的高阶函数,看起来花里胡哨,对我这个以Java言语为生产工具的安卓开发十分不友好,但是为了能今后和他们一同更好的水群,我开端学习高阶函数,去了解它的魅力。

我将本篇归归于安卓开发基础必备系列,因为这部分常识归于开发言语基础常识,此外,高阶函数也是很多人推重Kotlin的魅力所在。

正篇

首要咱们看看Lambda编程,这个编程方法仍是我在用Java开发安卓时分用点击事件时被Warnings提示知晓的,AS引荐将匿名函数换为Lambda方法,再后面的学习中了解到这是一种语法糖

Lambda是计算机编程言语,Lambda表达式是一个匿名函数,它能够包括表达式和语句,并且可用于创建托付或表达式目录树类型。

语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得约翰兰达(Peter J. Landin)发明的一个术语,指计算机言语中添加的某种语法,这种语法对言语的功能并没有影响,但是更便利程序员运用。一般来说运用语法糖能够增加程序的可读性,然后削减程序代码犯错的机会。

Warning提示我引荐替换成Lambda表达式:

安卓语言基础之Kotlin高阶函数——Lambda表达式(一)

vHello.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    }
});

替换为:

vHello.setOnClickListener(v -> {
});

以上是Lambda表达式的一个比方,下面咱们来详细看看这种编程方法:

调集的函数式API

咱们一般去寻调集种元素长度最长的写法如下Demo:

val list = listOf("Apple", "Banana", "Pear")
var maxLengthFruit = ""
for (fruit in list) {
    if (fruit.length > maxLengthFruit.length) {
        maxLengthFruit = fruit
    }
}
println("max length fruit is $maxLengthFruit")

而如果咱们运用调集的函数式API就非常简练:

val list = listOf("Apple", "Banana", "Pear")
val maxLengthFruit = list.maxBy { it.length }
println("max length fruit is $maxLengthFruit")

一段for循环直接简化为一句,但关于不熟悉这种表达方法的就会一头雾水,最早我接触的时分就感觉不利于阅览,其实学完后就感觉这种写法仍是很爽的,接下来,为了看懂这种写法,咱们先了解一下Lambda,它就是一小段能够作为参数传递的代码,一般情况下咱们编程都是向某个函数传参时传入变量,但Lambda能够做到传入一小段代码,而且其实这一小段的界说中未规则长短(一般不主张在Lambda表达式编写过长的代码,避免影响代码可读性)。

Lambda表达式的语法结构如下:

{参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}

咱们能够看到,最外层是大括号,然后内部首要声明晰参数列表,然后用“->”符号连接结尾的函数体,表明参数列表完毕和函数体开端,函数体能够编写咱们想完成的逻辑代码(不主张过长),终究位于终究一行的代码会自动作为Lambda表达式的回来值。

当然这是完好的写法,此外还有更为简化的版本,不过首要咱们需要先了解Lambda的完好表达式,便利向更深层学习。

了解了完好的表达式,咱们来一步步看怎么简化到之前的代码的:

maxBy其实是一个普通的函数,它能够承受一个Lambda类型的参数,并会遍历调集时每次遍历的值作为参数传递给Lambda表达式,也就是能够根据咱们传入的条件来遍历调集,然后找到该条件下的最大值。

知晓了maxBy函数,那么首要,咱们能够根据完好表达式写出如下代码:

val list = listOf("Apple", "Banana", "Pear")
val lambda = { fruit: String -> fruit.length}
val maxLengthFruit = list.maxBy(lambda)
println("max length fruit is $maxLengthFruit")

咱们将Lambda表达式作为参数传入了maxBy函数中,但其实是能够去简化该写法的,因为咱们不需要专门去界说一个lambda变量,直接将其视为参数传入该函数中:

val list = listOf("Apple", "Banana", "Pear")
val maxLengthFruit = list.maxBy({ fruit: String -> fruit.length})
println("max length fruit is $maxLengthFruit")

此时,编译器会报Warning:

安卓语言基础之Kotlin高阶函数——Lambda表达式(一)
这告知咱们当Lambda参数是函数的仅有一个参数时,能够将函数的括号省掉:

val list = listOf("Apple", "Banana", "Pear")
val maxLengthFruit = list.maxBy { fruit: String -> fruit.length }
println("max length fruit is $maxLengthFruit")

因为Kotlin有类型推导机制,所以咱们的Lambda表达式的参数列表在大多数情况下其实不必声明参数类型,所以咱们进一步将其简化:

val maxLengthFruit = list.maxBy { fruit -> fruit.length }

而Lambda表达式在参数列表中只要一个参数时乃至不必声明参数名,即可用it关键字来替代,所以终究变成咱们最初看到的那个最简代码:

val maxLengthFruit = list.maxBy { it.length }

其他常用的调集函数式API

除了maxBy函数API以外,还有好几个很好用的调集函数式API,比方:

map函数

这个函数用于将调集的每个元素都映射成别的的值,映射规则在Lambda表达式中指定,然后生成一个新的调集,如下Demo:

val list = listOf("Apple", "Banana", "Pear")
val newList = list.map { it.uppercase(Locale.getDefault()) }
for (fruit in newList) {
    println(fruit)
}

上述代码将list的元素全部变为大写,然后生成新的列表。

filter函数

这个函数能够用来过滤调集的一些数据,能够独自运用也能结合map函数一同运用,如下demo:

val newList = list.filter { it.length <= 5 }
    .map { it.uppercase(Locale.getDefault()) }

上面代码能够将生成的新列表元素长度控制在5个字符以内。

any与all函数

any函数能够用于判别调集中是否至少存在一个元素满意指定条件,而all函数则用于判别调集中是否一切元素都满意指定条件,如下demo:

val anyResult = list.any { it.length <= 5 }
val allResult = list.all { it.length <= 5 }
println("anyResult is $anyResult, allResult is $allResult")

上面代码条件设置为元素长度是否在5个字符以内,allResult要一切元素满意该条件才能true,而anyResult只要有一个元素满意条件即回来true。

总结

本篇主要是叙述了Lambda编程中调集的函数式API用法,是Kotlin高阶函数的前置第一篇,下一篇咱们看看Lambda编程的Java函数式API的用法,其实就是开篇提到的点击事件的那种类型,然后咱们再去探求Kotlin中的高阶函数怎么去写。