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表达式的话,可以用
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val lambda = {fruit: String -> fruit.length}
val maxLengthFruit = list.maxBy(lambda)
然后对他进行简化,首先
val maxLengthFruit = list.maxBy({fruit: String -> fruit.length})
然后
val maxLengthFruit = list.maxBy(){fruit: String -> fruit.length}
如果lambda参数是函数唯一参数的话,还可以直接省略():
val maxLengthFruit = list.maxBy{fruit: String -> fruit.length}
然后加上it
代替:
val maxLengthFruit = list.maxBy{it.length}
这样一步步推导就可以推导出最简形式了。
map函数
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函数
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。单抽象方法接口指这个接口中只有一个待实现的方法。比如线程中的run()
方法:
public interface Runnable {
void run();
}
我们在
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.\n")
for(fruit in list) {
builder.append(fruit).append("\n")
}
val result = builder.toString()
println(result)
用with
方法就可以改成:
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val result = with(StringBuilder()) {
append("Start eating fruits.\n")
for(fruit in list) {
append(fruit).append("\n")
}
toString()
}
println(result)
另外,还有个run
函数和这个类似,只不过run函数是在某个对象的基础上使用,同样接受lambda表达式,其他则是一样的,最后一行返回值:
val result = obj.run {
//上下文
"value"
}
apply
apply函数也很类似,只不过他不会返回一个值,而是自动返回调用对象本身:
val resullt = obj.apply {
//上下文
}
// result == obj
比如