函数式接口
一种编程范式,主要关注处理数据的函数
函数式接口是指有且仅有一个抽象方法的接口,可以使用@Functionallnterface注解进行标识,函数式接口可以用Lambda表达式来实现,从而简化代码的编写
java
@Functionallnterface
interface 接口名{
唯一的抽象方法
}
函数式接口的注意事项
1,函数式接口的准确定义为有且有且仅有一个抽象方法需要重写
在接口中添加Object类中的方法作为抽象方法,子类可以不重写
Lambda表达式介绍
jdk8引入
只能操作函数式接口
当需要一个函数式接口的实现类对象时使用
1,概述
Lambda表达式由三个部分组成,参数列表,箭头符号和方法体
(parameters)-> {方法体}
Lambda的完全形式
java
(T 参数1,T 参数2) -> {语句1;
语句2;}
参数列表:包含在括号中,可以省略参数类型
即函数式接口中唯一抽象方法的参数
箭头符号:由"->"组成,将参数和方法体分开
方法体:可以是表达式或者语句块
即函数式接口唯一抽象方法的重写形式
Lambda表达式的应用场景:
1,使用Lambda表达式可以简化匿名内部类的使用
2,可以作为方法参数传递,用于简化回调函数的编写
3,可以用于集合的遍历和筛选操作,简化代码-->Stream流体现
Lambda表达式代码实现:
1,无参无返回值情况
java
@FunctionalInterface
2 interface NoParamNoReturn {
3 void execute();
4 }
// ⽆参⽆返回值的情况
27 public static void executeNoParamNoReturn(NoParamNoReturn func) {
28 func.execute();
29 }
在executeNoParamNoReturn()方法中传入一个NoParamNoReturn接口类型的参数,需要传入一个接口类型的实现类对象,
在之前,我们通常使用匿名内部类进行传入,但是当这个接口中有且仅有一个需要重写的抽象方法时,即这个接口为函数式接口时
我们可以使用Lambda表达式进行简化
java
public static void main(String[] args) {
executeNoParamNoReturn(()->{
System.out.println("已传递");
});
}
调用方法,传入lambda表达式,因为没有参数列表,所以在小括号中无需传入参数,在方法体中因为没有返回值,所以不需要return语句.
传递完接口实现类对象,方法内执行接口实现类对象重写的execute()方法,即输出"已传递".
再来看看其他情况
2,有参有返回值情况
java
@FunctionalInterface
interface WithParamWithReturn {
int add(int a, int b);
}
//有参有返回值的情况
public static int executeWithParamWithReturn(WithParamWithReturn func, int a, int b) {
return func.add(a, b);
}
public static void main(String[] args) {
System.out.println(executeWithParamWithReturn((int c,int d)->{
System.out.println(1);
return c+d;},1,2));
}
在测试方法中我们调用executeWithParamWithReturn()方法,可以看到需要传入三个参数:
一个WithParamWithReturn接口类型的实现类对象,
一个int类型的 a
一个int类型的 b
在main方法中我们在需要实现类对象的位置传入lambda表达式
java
(int c,int d)->{
System.out.println(1);
return c+d;
}
因为接口内的抽象方法要求传入两个int类型的参数,所以我们相对的也需要传入两个int类型的参数
即小括号内的c 和 d
又因为抽象方法要求一个int类型的返回值,所以我们相对的也需要在返回语句中return一个int类型的值
即return c+d
在方法体中我们又自由发挥了一行语句,输出了一个1
分析到此结束,我们来看一下执行流程
首先在main方法中调用executeWithParamWithReturn()方法,传入WithParamWithReturn类型参数,
即lambda表达式
再传入int类型参数1和2
执行executeWithParamWithReturn()中的方法体
java
return func.add(a, b);
返回了接口实现类对象重写的方法的返回值
而我们重写的方法的方法体如下所示
java
System.out.println(1);
return c+d;
在输出1的同时,返回了c+d,也就是参数列表中的a+b,也就是3
再返回给方法调用者executeWithParamWithReturn(),再返回给其调用者主方法
java
public static void main(String[] args) {
System.out.println(executeWithParamWithReturn((int c,int d)->{
System.out.println(1);
return c+d;},1,2));
}
在主方法中我们将返回值打印
所以最后控制台的结果如下
3,lambda表达式的简化
lambda表达式的简化
参数列表中的类型可以省略
参数列表中如果只有一个参数可以省略小括号
方法体中如果只有一句语句可以省略大括号和分号
如果这行代码是return语句,return必须省略
先写一个完整的lambda表达式
java
@FunctionalInterface
interface Test {
int test(int a);
}
public static void main(String[] args) {
Test test = (int a)->{return a+1;};
System.out.println(test.test(1));
}
在省略参数类型,参数括号和方法体括号和分号以及return后我们得到
java
public static void main(String[] args) {
Test test = a->a+1;
System.out.println(test.test(1));
}
有一种热兵器暴打原始人的感觉...
总结:
lambda表达式是一种语法糖,极大的简化了对接口进行创建实现类对象的操作,在接口为函数式接口的前提下完全替代了匿名内部类,使代码显得更加简洁精练.