lambda编程,即把函数作为基本运算单元,函数可以作为变量,可以接收函数,还可以返回函数,故而也是函数式编程。kotlin支持lambda编程,而Java只有1.8之后的版本才开始加入相关语法支持。
传统方式上,我们创建一个List集合ArrayList,而后需要调用add函数一个个将集合的内容添加进集合中,例如:
val list = ArrayList<String>()
list.add("Joey")
list.add("Kevin")
list.add("Brance")
liust.add("Jegret")
而kotlin提供一个内置函数listOf()
来实现这一些列操作:
val list = listOf("Joey","Kevin","Brance","J-egret")
仅需一行代码就可以实现集合的初始化操作。需要注意的是,listOf()
函数是一个不可变函数,仅能用于读取,无法对集合进行增删改。如果需要创建一个可变的集合,需要用到的方法是mutableListOf()
:
val set = mutableListOf("Joey","Kevin","Brance","J-egret")
set.add("Jack")
以上方法为List集合用法,Set集合中用法类似,函数名为setOf()
、mutableSetOf()
。Map集合也与其类似,不同之处在于,Map集合是一种键值对形式的数据结构,因此,需要给上述的变量人名添加编号值,利用函数简化的写法是:
val map = mapOf("Joey" to 1,"Kevin" to 2,"Brance" to 3,"J-egret" to 4)
在上面创建的集合中,如果我们想要找到名字最长的那个人,以往我们可能会使用for遍历的方式,来对集合中的每一个元素进行两两比较,然后找出符合我们要求(名字最长)的那一个。而如果使用集合的函数API,则会使代码变得很简洁,实现也变得更简单:
val list = listOf("Joey","Kevin","Brance","J-egret")
val maxLength = list.maxBy{it.length}
print(maxLength)
由这段代码我们引申出Lambda表达式的定义:Lambda是一小段可以作为参数传递的代码。以往,我们向某个函数传递参数时只能传入变量,例如Int变量、String变量等,而借助Lambda就可以被允许传入一小段代码。Lambda表达式的语法结构为:
{参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}
首先最外层的是一对大括号,如果有参数传入Lambda表达式中的话,我们还需要声明参数列表,参数列表的结尾使用的是->符号,表示参数列表的结束以及函数体的开始,在函数体中可以执行任意行代码(不建议太多太长),最后一行代码会自动作为Lambda表达式的返回值。
在上述的查找名字长度的例子中,maxBy函数就是可以接受Lambda参数的函数,并且会在遍历集合时将每次遍历的值传递给Lambda表达式,他的工作原理是根据传入的条件来遍历集合,从而找到该条件下的最大值。如果完整按照Lambda表达式的定义来编写上面的例子的话,那么应该如下所示:
val list = listOf("Joey","Kevin","Brance","J-egret")
val lambda = {name: String -> name.length}
val maxLength = list.maxBy(lambda)
由于maxBy函数可以直接传入lambda表达式,所以我们可以不用单独声明一个lambda变量:
val maxLength = list.maxBy({name: String -> name.length})
并且kotlin中规定,当Lambda参数是函数的最后一个参数时,可以将lambda表达式移到括号外面;若是Lambda表达式是函数的唯一一个参数的话,还可以将函数的括号移除:
val maxLength = list.maxBy{name: String -> name.length}
又由于kotlin可以自动对类型进行推导,所以可以省略去String参数声明;最后,当Lambda表达式的参数列表只有一个参数是,连参数名都可以省略,直接使用it代替,所以最后的代码就变成了如上所示的:
val maxLength = list.maxBy{it.length}