您现在的位置是:首页 >其他 >Kotlin中的lambda函数式API编程网站首页其他
Kotlin中的lambda函数式API编程
lambda函数式编程
lambda表达式结构是:{参数名: 参数类型, 参数名: 参数类型 … -> 函数体}(参数1, 参数2, …)
如我们要找出字符串数组的最长的那个单词,可以写成:
fun main() {
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
var maxLengthFruit = ""
for (fruit in list) {
if(fruit.length > maxLengthFruit.length) {
maxLengthFruit = fruit
}
}
println(maxLengthFruit)
}
如果我们想写成lambda表达式的话,可以用 maxBy exttt{maxBy} maxBy这个函数,该函数工作原理是接收一个lambda表达式,根据传入的条件来找到最大值。那么上述的代码就可以写成:
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val lambda = {fruit: String -> fruit.length}
val maxLengthFruit = list.maxBy(lambda)
然后对他进行简化,首先 maxBy exttt{maxBy} maxBy里面可以直接传lambda参数:
val maxLengthFruit = list.maxBy({fruit: String -> fruit.length})
然后 Kotlin exttt{Kotlin} Kotlin还规定,当lambda参数是函数最后一个参数时,可以将{}放在()后面:
val maxLengthFruit = list.maxBy(){fruit: String -> fruit.length}
如果lambda参数是函数唯一参数的话,还可以直接省略():
val maxLengthFruit = list.maxBy{fruit: String -> fruit.length}
然后加上
Kotlin
exttt{Kotlin}
Kotlin的优秀推导类型的机制,可以直接省略类型,然后当参数只有一个时,可以直接用it代替:
val maxLengthFruit = list.maxBy{it.length}
这样一步步推导就可以推导出最简形式了。
map函数
map exttt{map} map函数非常常用,可以把集合的每个元素都映射成另一个值,规则则是由接受的lambda表达式决定。比如我们要将水果名变成大写:
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val newList = list.map{it.toUpperCase()}
for(fruit in newList) {
println(fruit)
}
运行结果就是:
APPLE
BANANA
ORANGE
PEAR
GRAPE
WATERMELON
filter函数
filter exttt{filter} filter函数可以过滤集合中的数据,也同样接受lambda表达式。,可以搭配 map exttt{map} map函数使用:
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val newList = list.filter{it.length < 5}
.map{it.toUpperCase{}}
for(fruit in newList) {
println(fruit)
}
运行结果就是PEAR了。
Java函数式API使用
当我们用Kotlin调用Java方法时,如果这个方法只接受一个Java单抽象方法接口参数就可以换成函数式API。单抽象方法接口指这个接口中只有一个待实现的方法。比如线程中的
Runnable
exttt{Runnable}
Runnable接口,就只有一个run()方法:
public interface Runnable {
void run();
}
我们在 Thread exttt{Thread} Thread类中接受一个 Runnable exttt{Runnable} Runnable参数:
new Thread(new Runnable() { //使用匿名内部类
@Override
public void run() {
System.out.println("Thread is running");
}
}).start();
在Kotlin中,没有new这个关键字,改成了object关键字:
Thread(object : Runnable {
override fun run() {
println("Thread is running")
}
}).start()
然后这个Thread类的写法符合函数API的形式,故可以简化:
Thread(Runnable {
println("Thread is running")
}).start()
然后如果Java方法参数列表只有一个Java单抽象方法接口参数,可以直接对接口名省略:
Thread({
println("Thread is running")
}).start()
然后根据上面的简化还可以将()省略:
Thread{
println("Thread is running")
}.start()
同样还有最常用的点击事件接口OnClickListener,也符合函数式API的形式:
botton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
Kotlin中则可以简化成:
button.setOnClickListener {
}
就可以精简很多代码了。
let,with,apply
这三个函数均提供了函数API编程接口,即能接受lambda表达式
let
obj.let {obj2 ->
//业务逻辑
}
在上述代码中会自动将obj参数传给obj2,为了防止重名才取不同的名字
并且当只有一个参数时,可以用it代替。如现在有一个study类,类中有readBooks(),doHomework()两个方法,可以变成:
fun doStudy(study: Study) {
study.let {
it.readBooks()
it.doHomework()
}
}
通常在判空时使用
with
with函数接收两个参数,第一个参数是任意类型的对象,第二个参数是lambda表达式,在lambda表达式中会提供第一个参数的上下文,并用最后一行作为返回值。如现在一个水果列表,要依次吃水果:
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val builder = StringBuilder()
builder.append("Start eating fruits.
")
for(fruit in list) {
builder.append(fruit).append("
")
}
val result = builder.toString()
println(result)
用with方法就可以改成:
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val result = with(StringBuilder()) {
append("Start eating fruits.
")
for(fruit in list) {
append(fruit).append("
")
}
toString()
}
println(result)
另外,还有个run函数和这个类似,只不过run函数是在某个对象的基础上使用,同样接受lambda表达式,其他则是一样的,最后一行返回值:
val result = obj.run {
//上下文
"value"
}
apply
apply函数也很类似,只不过他不会返回一个值,而是自动返回调用对象本身:
val resullt = obj.apply {
//上下文
}
// result == obj
比如 SharedPreference exttt{SharedPreference} SharedPreference中就可以使用apply简洁的添加数据。





U8W/U8W-Mini使用与常见问题解决
QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
stm32使用HAL库配置串口中断收发数据(保姆级教程)
分享几个国内免费的ChatGPT镜像网址(亲测有效)
Allegro16.6差分等长设置及走线总结