随笔博文

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

2022-12-15 12:42:44 michael007js 105

前言

上一篇(安卓语言基础之Kotlin高阶函数——Lambda表达式(一) - 掘金 (juejin.cn))我们学习了Kotlin中Lambda表达式与其在集合的函数式API中的使用方法,本篇我们继续学习,去探究Lambda编程在安卓Kotlin开发中的其他地方的运用方法。

正篇

除了我们上一篇所说的一些集合的函数式API,其实Kotlin中调用Java方法也能用函数式API,也是使用了Lambda表达式,下面我们就来看看它们的用法。

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表达式为方法唯一参数,也能将方法括号去除:

image.png

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)

image.png使用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打印结果是一样的:

image.png

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)

简化一些,而且传的参数越多越明显。


首页
关于博主
我的博客
搜索