不知不觉间,2月份就过去,也就是说2018年已经过去了六分之一,再细想真可怕。
今天继续Kotlin
的学习,主要从lambda
的历史,定义,和集合的函数API,以及推荐使用的with
和apply
两个常用的函数。
Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包。在Java8
中,加入了lambda表达式,可以简化代码,方便开发者开发更高效的代码。
其表达式很简单:
(argument) -> (body)
lambda
编码了一小块你可以用作一个值进行传递的行为。它可以被独立的声明并存储在一个变量中。但是更常见的是,当它被传递给一个函数时直接声明。在Kotlin
中,一个lambda
表达式往往被一个大括号所包围,如下段代码:
val sum = { x: Int, y: Int -> x + y }
用java实现可能如下:
int sum(int x,int y) {
return x + y;
}
为了更好简化代码,lambda
表达式也是越来越简短,我们就用点击一个button时,打印对应的view的id,如代码如下:
btn?.setOnClickListener({ v ->
print(v.id)
})
当lambda
表达式作为参数时,且是参数列表里的最后一个参数,可以把{}放到外面:
btn?.setOnClickListener(){ v ->
print(v.id)
}
当lambda是函数的唯一参数时,你也可以删掉空的圆括号:
btn?.setOnClickListener{ v ->
print(v.id)
}
函数式风格代码,简化了代码,使得代码不被各种逻辑分离,其中集合也提供一些常见的函数式API,使得我们的开发事半功倍。
记得之前学习RxJava时有这两个函数,在Kotlin中其实也很类似,可以参考RxJava来理解这两个函数(filter, map)。
val nums = listof(1, 4, 8, 9)
list.filter{ it % 2 == 0} // 偶数
打印结果是
[2, 4]
filter里面实际上返回的是个boolean值,只有返回值为true才会被留下,当然返回值依然是之前的类型(如例子中的list返回依然是list)
val nums = listof(1, 2, 4, 5)
list.map{ it *it } //
打印结果是
[1, 4, 16, 25]
all是所有都满足指定条件(预言)才返回true,any则判断至少有一个满足条件,find则查找第一个指定条件,count表示满足预言的元素个数。
将指定维度的条件分组,将指定维度下的相同元素进行分组,返回是map类型
fun alphabet(): String {
val result = StringBuilder()
for (letter in 'A'..'Z') {
result.append(letter)
}
result.append("\nNow I know the alphabet!")
return result.toString()
}
由于在代码大量使用result
, 写起来很是麻烦。
fun alphabet(): String {
val stringBuilder = StringBuilder()
return with(stringBuilder) { // 1 在你调用的方法中制定接收器的值
for (letter in 'A'..'Z') {
this.append(letter) // 2 通过显式的“this”调用接收器值的方法
}
append("\nNow I know the alphabet!") // 3 调用方法,忽略“this”
this.toString() // 4 从lambda中返回值
}
}
文中的this都可以都可以忽略,不过有时需要alphabet内写这个类的this对象时,可以声明变量来实现。
apply基本上使用和with类似:
fun alphabet(): String {
val stringBuilder = StringBuilder()
return StringBuilder().apply { // 1 在你调用的方法中制定接收器的值
for (letter in 'A'..'Z') {
this.append(letter) // 2 通过显式的“this”调用接收器值的方法
}
append("\nNow I know the alphabet!") // 3 调用方法,忽略“this”
// 4 从lambda中返回值
}.toString()
}
二者的不同主要在返回值,用with返回值不是stringBuilder
自己的类型,而apply返回则仍然是StringBuilder
类型。