安卓语言基础之Kotlin高阶函数——Lambda表达式(二)
上一篇()我们学习了Kotlin中Lambda表达式与其在集合的函数式API中的使用方法,本篇我们继续学习,去探究Lambda编程在安卓Kotlin开发中的其他地方的运用方法。
正篇
Java函数式API的使用
在Kotlin中调用Java方法使用函数式API是有限制的,具体来说就是如果调用Java方法且该方法接受一个Java单抽象方法接口(指接口中只有一个待实现方法)参数,就能使用函数式API,如果遇到接口中有多个待实现方法就没法使用函数式API,Kotlin中使用Java函数式API的Demo(使用Runnable接口)如下:
val thread = Thread(Runnable {
println("Thread is running")
}).start()
当然,根据上一篇,我们还能再简化,因为当Lambda表达式为方法最后一个参数时,可以将Lambda表达式移动到方法括号外面,而如果Lambda表达式为方法唯一参数,也能将方法括号去除:
val thread = Thread {
println("Thread is running")
}.start()
还有我们之前文章中说到的点击事件监听,Kotlin也更加简短:
binding.saveButton.setOnClickListener {
//write code
}
以上就是Java函数式API的使用,十分的简单,但Java函数式API的使用都限于从Kotlin中调用Java方法且单抽象方法接口也必须是用Java语言定义的,因为Kotlin中有专门的高阶函数来实现更厉害的自定义函数式API功能,不需要像Java那样借助单抽象方法接口来实现,下面我们就来看看标准函数的用法。
标准函数
这里的标准函数指的是Standard.kt文件中定义的函数,因为涉及到Lambda表达式,所以在此介绍其中几个常用的方法
with函数
有两个参数,第一个参数是任意类型的对象,第二个参数则为一个Lambda表达式。 with函数将第一个参数作为Lambda表达式中对象的上下文,并使用Lambda表达式中最后一行代码作为返回值返回,如下:
val result = with(binding) {
//dialogHeight对象的上下文
"value"//with函数的返回值
}
应用Demo
比方说我们有个水果的列表,然后开始吃,吃完所有水果,我们依次打印出来 原本写法:
val lists = listOf("Apple", "Pear")
val builders = StringBuilder()
builders.append("eating.\n")
for (fruit in lists) {
builders.append(fruit).append("\n")
}
builders.append("All fruits.")
val res = builders.toString()
println(res)
但使用with,我们可以更简单的表示:
val list = listOf("Apple", "Pear", "Banana")
val result = with(StringBuilder()) {
for (fruit in list) {
append(fruit).append("\n")
}
append("All fruits.")
toString()
}
println(result)
使用with函数后我们就不用一直使用对象去调用方法,重复去写对象名,而是直接在with函数中传对象参数后的Lambda表达式中直接调用其方法,最后一句作为返回即可。
run函数
与with函数相似,但不是直接调用而是在对象上调用,且只接受Lambda表达式这一个参数:
val listR = listOf("Apple", "Pear", "Banana")
val resultR = StringBuilder().run {
for (fruit in listR) {
append(fruit).append("\n")
}
append("All fruits.")
toString()
}
println(resultR)
与上面with打印结果是一样的:
apply函数
该函数结构体和上面的run函数类似,但返回结果不同,apply函数返回的不是Lambda表达式最后一句而是调用方法的对象本身,所以我们代码也随之变化:
val listA = listOf("Apple", "Pear", "Banana")
val resultA = StringBuilder().apply {
for (fruit in listA) {
append(fruit).append("\n")
}
append("All fruits.")
}
println(resultA.toString())
介绍完这几种函数,其实它们之间很明显都可以相互转换,只是用法上的区别要注意好,此外,这些方法通常用于在重复写对象名调用方法时用到,可以写出更简洁的代码,比如使用intent传参跳转: 原本写法:
val intent = Intent(this, WebViewTest::class.java)
intent.putExtra("param1", "data1")
intent.putExtra("param2", "data2")
intent.putExtra("param3", "data3")
this.startActivity(intent)
使用apply函数后
val intents = Intent(this, WebViewTest::class.java).apply {
putExtra("param1", "data1")
putExtra("param2", "data2")
putExtra("param3", "data3")
}
this.startActivity(intents)