课本上说编程有两种模式,面向过程的编程以及面向对象的编程,其实在面向对象编程之前还出现了面向函数的编程(函数式编程),以前一直被忽略、不被重视,现在从学术界已经走向了商业界,对函数编程语言的支持目前有Scala、Erlang、F#、Python、Php、Java、Javascript等,有人说他将会是编程语言中的下一个主流…
函数式接口(Functional Interface)是Java 8对一类特殊类型的接口的称呼。 这类接口只定义了唯一的抽象方法的接口(除了隐含的Object对象的公共方法), 因此最开始也就做SAM类型的接口(Single Abstract Method)。
JDK中已有的一些接口本身就是函数式接口,如Runnable。 JDK 8中又增加了java.util.function包, 提供了常用的函数式接口。
函数式接口代表的一种契约, 一种对某个特定函数类型的契约。 在它出现的地方,实际期望一个符合契约要求的函数。 Lambda表达式不能脱离上下文而存在,它必须要有一个明确的目标类型,而这个目标类型就是某个函数式接口。
Java8教程可以查看到其他java8的新特性
举例:
1,无参数
interface IWay0{
void gotoSchool();
}
IWay0 way0 = () ->{
System.out.println("way0:来到学校了");
};
way0.gotoSchool();
2,一个或多个参数
interface IWay1{
void gotoSchool(String name);
}
interface IWay2{
void gotoSchool(String name, String tool);
}
//含有参数
IWay1 way1 = (name) ->{
System.out.println("way1:" + name + "来到学校了");
};
way1.gotoSchool("小明");
IWay2 way2 = (name, tool) ->{
System.out.println("way2:" + name + tool + "来到学校了");
};
way2.gotoSchool("小明","踩单车");
安卓中具体使用:
原始用法:
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(e, "click");
}
});
Lambda表达式:
mBtn.setOnClickListener((v) ->{
Log.i(e, "click");
});
当函数方法只调用单个静态方法时,可以使用
interface IWay0{
void gotoSchool();
}
interface IWay1{
void gotoSchool(String name);
}
interface IWay2{
void gotoSchool(String name, String tool);
}
interface IWay3{
void gotoSchool(String name, String tool, int time);
}
static class Clocker{
public static void clock(){
System.out.println("放学了,同学们回家吧");
}
public static void clock(String name){
System.out.println("放学了" + name + "回家");
}
public static void clock(String name, String tool){
System.out.println("放学了" + name + tool + "回家");
}
public static void clock(String name, String tool, int time){
System.out.println(time + "点钟放学了" + name + tool + "回家");
}
}
//只调用单个静态方法
IWay0 way00 = Clocker::clock;
way00.gotoSchool();
IWay1 way11 = Clocker::clock;
way11.gotoSchool("小红");
IWay2 way22 = Clocker::clock;
way22.gotoSchool("小红", "走路");
IWay3 way33 = Clocker::clock;
way33.gotoSchool("小红", "走路", 5);
输出:
放学了,同学们回家吧
放学了小红回家
放学了小红走路回家
5点钟放学了小红走路回家
其实就是函数方法的引用的复用,比如已经实例化了一个a变量,需要复用a变量中的m方法,只需要b = a::m,b.m()即可,前提a对应的class是函数式接口
//没有参数
IWay0 way0 = () ->{System.out.println("way0:来到学校了");};
way0.gotoSchool();
//含有参数
IWay1 way1 = (name) ->{System.out.println("way1:" + name + "来到学校了");};
way1.gotoSchool("小明");
//等同于IWay0 way01 = () ->{System.out.println("way0:来到学校了");};
IWay0 way01 = way0::gotoSchool;
way01.gotoSchool();
//等同于IWay1 way1 = (name) ->{System.out.println("way1:" + name + "来到学校了");};
IWay1 way02 = way1::gotoSchool;
way02.gotoSchool("小刚");
输出
way0:来到学校了
way1:小明来到学校了
way0:来到学校了
way1:小明来到学校了
Class::new,得到的是一个函数式接口
static class Way0{
private String mTool = "骑单车";
public Way0(){}
public Way0(String tool){
mTool = tool;
}
@Override
public void gotoSchool() {
System.out.println("我要" + mTool + "去上学了");
}
}
//需要借助函数式接口
@FunctionalInterface
interface WayInterface1{
Way0 create();
}
@FunctionalInterface
interface WayInterface2{
Way0 create(String name);
}
WayInterface1 wayInterface = Way0::new;
Way0 iway1 = wayInterface.create();
iway1.gotoSchool();
WayInterface2 wayInterface2 = Way0::new;
Way0 iway2 = wayInterface2.create("走路");
iway2.gotoSchool();
输出
我要骑单车去上学了
我要走路去上学了