Lambda表达式
在Java 8的时候开始支持Lambda表达式,目前Lambda语法在Java中已经被广泛的运用,Lambda表达式可以理解为是一种语法糖,值得庆幸的是,Kotlin一经开源成熟就已经支持这种语法。
Lambda表达式的本质其实是匿名方法,因为在其底层实现中还是通过匿名方法来实现的。但是我们在用的时候不必关心起底层实现。不过Lambda的出现确实是减少了代码量的编写,同时也是代码变得更加简洁明了。
Lambda作为方法式编程的基础,其语法也是相当简单的。这里先通过一段简单的代码演示没让大家了解Lambda表达式的简洁之处:
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Lambda简洁之道", Toast.LENGTH_LONG).show();
}
});
1
2
3
4
5
6
2
3
4
5
6
VS
view.setOnClickListener {
v -> Toast.makeText(v.context, "Lambda简洁之道", Toast.LENGTH_LONG).show()
}
1
2
3
2
3
# Lambda表达式的特点
view.setOnClickListener {
v -> Toast.makeText(v.context, "Lambda简洁之道", Toast.LENGTH_LONG).show()
}
1
2
3
2
3
- 一是匿名方法
- 二是可传递
# Lambda语法
无参数的情况 :
val/var 变量名 = { 操作的代码 }
1
有参数的情况
val/var 变量名 : (参数的类型,参数类型,...) -> 返回值类型 = {参数1,参数2,... -> 操作参数的代码 }
1
可等价于
// 此种写法:即表达式的返回值类型会根据操作的代码自推导出来。
val/var 变量名 = { 参数1 : 类型,参数2 : 类型, ... -> 操作参数的代码 }
1
2
2
lambda表达式作为方法中的参数的时候,这里举一个例子:
fun test(a : Int, 参数名 : (参数1 : 类型,参数2 : 类型, ... ) -> 表达式返回类型){
...
}
1
2
3
2
3
实例:
/**
* lambda表达式作为方法中的参数的时候。定义transform方法,可以对数组中的元素进行变换。
* @param array 要求传入一个数组,元素类型为Int整数类型
* @param action 要求传入的是一个方法,接受两个参数下标index,元素element。要求返回变换后的元素,会替换掉老的元素
*/
fun transform(array: Array<Int>, action: (index: Int, element: Int) -> Int) {
for (index: Int in array.indices) {
val newValue: Int = action(index, array[index])
array[index] = newValue
}
}
fun main(args: Array<String>) {
val nums = arrayOf(1,2,3,4)
// 方法外传入调用
transform(nums, action = { index, element ->
index * element // 返回值
})
// 方法外入调用
transform(nums) {
index, element -> index * element * 2
}
println(nums.contentToString())
}
>>> [0, 2, 6, 12]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Lambda实践
# 如何使用it
it
并不是Kotlin中的一个关键字(保留字)it
是在当一个高阶方法中Lambda表达式的参数只有一个的时候可以使用it来使用此参数it
可表示为单个参数的隐式名称,是Kotlin语言约定的
实例A:单个参数的隐式名称
// 这里举例一个语言自带的一个高阶方法filter,此方法的作用是过滤掉不满足条件的值。
val arr = arrayOf(1,3,5,7,9)
// 过滤掉数组中元素小于2的元素,取其第一个打印。这里的it就表示每一个元素。
println(arr.filter { it < 5 }.component1())
//结合上文的
testClosure(1)(2) {
println(it)
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
实例B:打印集合中元素和下标
fun main(args: Array<String>) {
val list = arrayListOf<Int>(1, 2, 3, 4, 5, 6)
// 具名参数使用
list.forEachIndexed(action = {index: Int, element: Int ->
println("forEachIndexed: $index -> $$element")
})
// 括号外使用(非具名参数)
list.forEachIndexed { index: Int, element: Int ->
println("forEachIndexed: $index -> $$element")
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 如何使用下划线_
在使用Lambda表达式的时候,可以用下划线(_)表示未使用的参数,表示不处理这个参数。
在遍历一个Map集合的时候,这当非常有用
val map = mapOf("key1" to "value1", "key2" to "value2", "key3" to "value3")
map.forEach { (key, value) ->
println("$key \t $value")
}
// 不需要key的时候
map.forEach { (_, value) ->
println(value)
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
编辑 (opens new window)
上次更新: 2022/06/04, 11:36:35