Lamda表达式学习
参考:
http://blog.csdn.net/xmxkf/article/details/51532028#3-函数式接口functional-interfaces
http://colobu.com/2014/10/28/secrets-of-java-8-functional-interface/
http://www.cnblogs.com/ownraul/p/5551545.html
简介:
Lamda表达式是java SE 8 中出来的。主要针对的是由于内部类带来的冗余语法的问题。
Eg:
textView.setOnClickListener(newView.OnClickListener(){
@Override
publicvoid onClick(View v) {
Toast.makeText(getApplicationContext(), "helloLambda", Toast.LENGTH_LONG).show();
}
});
经过处理之后为:
textView.setOnClickListener(
v -> Toast.makeText(getApplicationContext(),"Lambda", Toast.LENGTH_LONG).show());
因此,我们引入lamda语法主要要解决匿名内部类的:
1、 语法过于冗余
2、 类型载入和实例创建语义不够灵活(也就是泛型问题)
3、 减少了无法捕获非final的局部变量的影响
安卓中引入lamda
参看参考文章
lamda主要使用的规则
它可以替代的地方必须是“函数式接口”。
函数式接口代表的一种契约,一种对某个特定函数类型的契约。在它出现的地方,实际期望一个符合契约要求的函数。 Lambda表达式不能脱离上下文而存在,它必须要有一个明确的目标类型,而这个目标类型就是某个函数式接口:SAM类型的接口(Single Abstract Method)
早期的函数式接口:
l java.lang.Runnable
l java.util.concurrent.Callable
l java.security.PrivilegedAction
l java.util.Comparator
l java.io.FileFilter
l java.nio.file.PathMatcher
l java.lang.reflect.InvocationHandler
l java.beans.PropertyChangeListener
l java.awt.event.ActionListener
l javax.swing.event.ChangeListener
jdk8新增的函数式接口:
l Predicate -- 传入一个参数,返回一个bool结果,方法为boolean test(T t)
l Consumer -- 传入一个参数,无返回值,纯消费。方法为void accept(T t)
l Function -- 传入一个参数,返回一个结果,方法为R apply(T t)
l Supplier -- 无参数传入,返回一个结果,方法为T get()
自定义的函数式接口:
@FunctionalInterface
interface Converter<F, T> {
Tconvert(F from);
}
使用:
Converter<String, Integer> converter= (from) -> Integer.valueOf(from);
Integer converted =converter.convert("123");
Lamda语法:
ambda表达式的语法由参数列表、箭头符号->和函数体组成
无参数:
Interface3 in31 = ()-> {
Log.v(TAG, "吃饭了吗");
returntrue;
};
一个参数
Interface2 in21 = name->{
Log.v(TAG,"有这个人吗?");
Log.v(TAG,"没有啊");
returnfalse;
};
多个参数
Interface1 in2 = (name, age, addr) ->{
Log.v(TAG,"有这个人吗?");
Log.v(TAG,"没有啊");
returnfalse;
};
多个参数并赋予类型:
private void lambda3(){
Interface1 in1 = (String name, int age, String addr)->{
Log.v(TAG, "有这个人吗?");
Log.v(TAG, "没有啊");
return false;
};
}
在使用lamda需要注意的问题:
1、它不会从父类(supertype)中继承任何变量名,也不会引入一个新的作用域。lambda表达式函数体里面的变量和它外部环境的变量具有相同的语义。
class Activity{
button.setOnClickListener(v->{this.finish();})
}
this代表的是Activity对象,而不是OnClickListener对象;
如果你写成下面的样子:
class Activity{
button.setOnClickListener(new OnClickListener(View v){
this.xxx()
});
}
这个this就是指的OnClickListener这个匿名对象,如果你要用Activity对象,必须用Activity.this
2、不必再像内部内一样在用到外部的变量时还要转化为final才能用。