Kotlin:集合的函数是API,Lambda写法的优化过程

以下内容全部来自郭霖的《第一行代码》。

1
在一个水果集合里找到单词最长的那个水果,初步写法。

var list = listOf("Apple", "Banana", "Oriange", "Pear", "Grape", "Watermelon")
var maxLengthFruit = ""
for(fruit in list){
    if(fruit.length > maxLengthFruit.length){
        maxLengthFruit = fruit.length
    }
}

Log.i("_like", "maxLengthFruit is $maxLengthFruit")//Watermelon

优化1:使用maxByOrNull函数,maxByOrNull工作原理是根据我们传入的条件来遍历集合,从而找到该条件下的最大值。

val list = listOf("Apple", "Banana", "Oriange", "Pear", "Grape", "Watermelon")
val lambda = {fruit:String->fruit.length}
val maxLengthFruit = list.maxByOrNull(lambda)

Log.i("_like", "maxLengthFruit is $maxLengthFruit")//Watermelon

优化2:去掉Lambda变量。

val list = listOf("Apple", "Banana", "Oriange", "Pear", "Grape", "Watermelon")
val maxLengthFruit = list.maxByOrNull({fruit:String->fruit.length})

Log.i("_like", "maxLengthFruit is $maxLengthFruit")//Watermelon

优化3:Kotlin规定:当Lambda参数是函数的最后一个参数时,可以将Lambda表达式移到函数的括号外面。

val list = listOf("Apple", "Banana", "Oriange", "Pear", "Grape", "Watermelon")
val maxLengthFruit = list.maxByOrNull(){fruit:String->fruit.length}

Log.i("_like", "maxLengthFruit is $maxLengthFruit")//Watermelon

优化4:如果Lambda参数是函数的唯一一个参数的话,还可以将参数的括号省略。

val list = listOf("Apple", "Banana", "Oriange", "Pear", "Grape", "Watermelon")
val maxLengthFruit = list.maxByOrNull{fruit:String->fruit.length}

Log.i("_like", "maxLengthFruit is $maxLengthFruit")//Watermelon

优化5:kotlin有出色的类型推导机制,Lambda表达式中参数列表大多数情况下不必声明参数类型。

val list = listOf("Apple", "Banana", "Oriange", "Pear", "Grape", "Watermelon")
val maxLengthFruit = list.maxByOrNull{fruit->fruit.length}

Log.i("_like", "maxLengthFruit is $maxLengthFruit")//Watermelon

优化6:当Lambda表达式的参数列表中只有一个参数时,也不必声明参数名,可以使用it关键字来代替。

val list = listOf("Apple", "Banana", "Oriange", "Pear", "Grape", "Watermelon")
val maxLengthFruit = list.maxByOrNull{it.length}

Log.i("_like", "maxLengthFruit is $maxLengthFruit")//Watermelon

2
同理优化Java函数式API。

在kotlin中调用一个Java方法,并且该方法接受一个Java单抽象方法接口参数,就可以使用函数式API。Java单抽象接口指的是接口中只有一个待实现方法。如Runnable接口,只有一个待实现的run()方法。

Java:

new Thread(new Runnable(){
    @Override
    public void run(){
        ...
    }
}.start();

Kotlin:

Thread(object:Runnable {
    override fun run(){
        ...
    }
}).start()

由于Kotlin完全舍弃了new关键字,因此创建匿名类实例的时候就不能在使用new了,而是改用了object关键字。

优化1:Runnable类中只有一个待实现的方法,所及即使没有显式地重写run()方法,Kotlin也能自动明白Runnable后面的Lambda表达式就是要在run()方法中实现的内容。

Thread(Runnable { 
  ...
}).start()

优化2:一个Java参数列表中有且仅有一个Java单抽象方法接口参数,我们还可以将接口名进行省略。

Thread({
  Log.i("_like", "run")
}).start()

优化3:当Lambda表达式是方法的最后一个参数时,可以将Lambda移到方法括号的外面。同时,如果Lambda表达式还是方法的唯一参数,还可以将方法的括号省略。

Thread{...}.start()

由于Android SDK还是用Java编写的,当用Kotlin调用这些SDK接口时,就很可能用到这种Java函数式API写法。例如,使用Kotlin为一个Button按钮编写点击事件可简化为:button.setOnClickListener { ... }

你可能感兴趣的:(Kotlin:集合的函数是API,Lambda写法的优化过程)