Lambda在Android中的使用
Lambda语法在Android中的应用
0.作用
lambda是匿名函数的别名,用来简化匿名内部类,使用lambda的前提是编译器可以准确的推断出你需要哪个匿名内部类被简化。
0.1 例子
我们最常接触到的例子是view设置onClickListener:
|
|
使用lambda:
|
|
lambda不仅把对象名隐匿(View.OnClickLisetener
),更完成了方法名的隐匿(onClick(View v)
),展示了一个接口抽象方法最有价值的亮点:参数、实现方法
1.lambda表达式的形式
1.1 函数式接口
函数式接口是最基本的lambda表达式,其余的形式都是由其扩展而来
函数式接口是指有且只有一个抽象方法的接口, 比如各种Listener和Runnable接口。lambda表达式就是对这类接口的匿名接口内部类进行简化,基本形式如下:
(参数列表 ... ) -> { 语句块...}
面以 Java 提供的 Comparator 接口来展示一个实例,该接口常用于排序比较:
|
|
当编译器可以推到出具体的参数类型,可以忽略参数类型,简化:
|
|
当参数只有一个时, 参数列表可以去掉括号()
, 简化:
|
|
但是,当没有参数传入的时候,参数列表的括号就要保留:
|
|
当具体实现的处理逻辑只有一句的时候,也可以省略语句块的{}
:
|
|
当具体实现只有一句,并且是个return返回值的时候,这个表达式不用在表达式前面加retrun
:
|
|
1.2 方法引用
当我们使用函数接口的lambda的时候,进行逻辑实现的时候,我们既可以自己实现一系列处理,也可以调用已存在的方法,下面以 Java 的 Predicate 接口作为示例,此接口用来实现判断功能,我们来对字符串进行全面的判空操作:
|
|
我们知道,TextUtils.isEmpty()实现了上述功能,所以我们可以调用已存在的方法来进行逻辑判断:
|
|
当我们调用已存在的方法来进行逻辑判断,可以简化使用lambda的方法引用:
|
|
方法引用就是:当逻辑实现只有一句,且调用了已存在的方法进行处理(静态方法,this,super的方法也包括在内)时,对函数接口形式的lambda的进一步简化。传入方法的参数就是原接口的参数。
接下来总结三种方法引用的形式:
object::instanceMethod
直接调用任意对象的实例方法,如
obj::equals
代表调用了obj这个对象的equals方法与接口方法参数比较是否相等,效果等同于obj.equals(t)
。当前类的方法可以直接调用this::method
,父类方法同理。ClassName::staticMethod
直接调用某类的静态方法,并将接口方法参数传入,如上述
TextUtils::isEmpty
等同于TextUtils.isEmpty(s)
。
ClassName::instanceMethod
较为特殊,将接口方法参数列表的第一个参数作为方法调用者,其余参数作为方法参数。由于此类接口较少,故选择Java提供的BiFunctin接口作为示例,该接口接受一个T1类,T2类对象,并返回R对象:
1234567891011interface BiFunction<T1, T2, R> {R apply(T1 t1, T2 t2);}BiFunction<String,String,Boolean> biFunction=new BiFunction<String, String, Boolean>() {public Boolean apply(String s1, String s2){return s1.equals(s2);}};// ClassName 为接口方法的第一个参数的类名,同时利用接口方法的第一个参数作为方法调用者,其余参数作为方法参数,实现 s1.equals(s2);BiFunction<String,String,Boolean> biFunction= String::equals;
1.3 构造器引用
Lambda 表达式的第三种形式,其实和方法引用十分相似,只不过方法名替换为 new 。其格式为 ClassName :: new
。这时编译器会通过上下文判断传入的参数的类型、顺序、数量等,来调用适合的构造器,返回对象。
2. 一点玄学
2.1 this关键字
在匿名内部类中,this 关键字指向的是匿名类本身的对象,而在 lambda 中,this 指向的是 lambda 表达式的外部类。
2.2 方法数差异
前 Android Studio 对 Java 8 新特性编译时采用脱糖(desugar)处理,lambda 表达式经过编译器编译后,每一个 lambda 表达式都会增加 1~2 个方法数。而 Android 应用的方法数不能超过 65536 个。虽然一般应用较难触发,但仍需注意。