button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } });
kotlin :
button.setOnClickListener { }
是不是觉得少了很多行代码,整个代码整洁很多,一句话就直接代替了java中的匿名内部类的写法。这就是lambda编程。下面,我们来先了解下lambda编程
1. Lambda 和集合
先创建一个实例:person类 包含名字在和年龄
data class Person(val name: String,val age:Int)
假设我们有一个列表
val people = listOf(Person("小明",20),Person("小红",18),Person("小芳",17))
现在我们要从这个列表中找出年纪最大的那个人
java:
fun finTheOldest(people: List<Person>) { var maxAge = 0 var theOldest: Person? =null for (person in people) { if (person.age > maxAge) { maxAge = person.age theOldest = person } } println(theOldest) }
写一个循环的方法,传入这个列表,通过不断对比对比找到最大的那个数。这么写的代码量多,且容易报错。让我们看看kotlin怎么实现
kotlin:
people.maxBy{it.age}
kotlin就一行代码,为什么呢?因为由于lambda的帮助,在Kotlin中对集合很多的操作都被封装在了库里,避免了很多重复代码。maxBy{}实际上就是一个库函数
花括号的it.age就是实现这个逻辑的lambda,它接收一个集合中的元素作为实参(使用 it 引用它)并且返回用来比较的值 这个例子中集合元素是 Person 对象用来比较的是存储在其 age 属性中的年龄。就相当于 java中的finTheOldest()这个方法。
这个函数是简化后的函数,我们先看看lambda的语法,等下再回来简化这个函数。
写法就是
val sum = {x:Int,y:Int-> x+y}
转换成java就是
public int sum(int x,int y){ return x+y; }
x和y是传入的参数,x+y就是函数体。
那么我们来简化上面找最大年纪的例子,如果不用任何简明语法来写就是
people.maxBy ({ p:Person -> p.age })
people.maxBy (){ p:Person -> p.age }
people.maxBy { p:Person -> p.age }
如果lambda表达式参数的类型可以被推导出来,可以直接省略参数类型
people.maxBy { p -> p.age }
people.maxBy{it.age}
注意:并不是所有lambda都能简写的。
举个例子:
val getAge = {p:Person->p.age}
你用变量存储的这个lambda,则没有上下文推断参数类型的,所以你必须指定参数。
2.在作用域中访问变量
在函数的内部使用lambda时,可以访问在lambda前定义的局部变量
与Java不一样的是,Kotlin中的在lambda内部可以访问非final变量,甚至可以修改他们。我们称这些变量被lambda捕捉
3. 成员引用
val getAge = Person :: age
那么,这是一个更简洁的 Lambd 表达式,它做同样的事情:
val getAge = { person : Person -> person.age }
people.maxBy (Person :: age)
fun salute() = println("Salute !") run (::salute)
![](https://i-blog.csdnimg.cn/blog_migrate/17114577b772fc384e286a7cbcbb49f4.png)
也可以用构造方法引用
存储或者延迟执行创建类实例的动作
4.分析开头的点击事件
学完概念,我们回到开头讲的按钮点击事件,先写一个未做任何简化的点击事件
button?.setOnClickListener(object :View.OnClickListener{ override fun onClick(v: View?) { TODO("点击事件") } })
先简化方法
button?.setOnClickListener(View.OnClickListener{ TODO("点击事件") })
接下来简化接口 button?.setOnClickListener({ TODO("点击事件") })
最后去掉括号,就和我们上面写的一样了 button?.setOnClickListener{ TODO("点击事件") }
5.集合的函数式API
下面只举例几个例子:
filter
函数:
遍历集合并选出应用给定lambda后会返回true的那些元素
//使用filter函数,返回偶数集合 val datas = listOf(1, 2, 3, 4, 5) println(datas.filter { it % 2 == 0 })
filter
函数可以从集合中过滤我们不想要的元素,但是并不会改变这些元素
map
函数:
对集合中的每一个元素应用给定的函数,并将结果收集到一个新集合。
//将传入的数字列表,变成他们的平方的列表 val list = listOf(1, 2, 3) println(list.map { it * it })