Lambda表达式
1.1函数式编程思想概述
在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿数据做操作"
面向对象思想强调“必须通过对象的形式来做事情”
函数式思想则尽量忽略面向对象的复杂语法:“强调做什么, 而不是以什么形式去做”
而lambda就是函数式思想。
Lambda表达式的标准格式
格式: (形式参数)-> {代码块}
形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可。
->:由英文中画线和大于符号组成,固定写法。代表指向动作。
代码块:是我们具体要做的事情,也就是以前我们写的方法体内容。
使用lambda表达式的一个demo:
public class LambdaDemo {
public static void main(String[] args) {
//使用匿名内部类启动多线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("多线程启动了");
}
}).start();
//使用lambda方式启动多线程
new Thread(()->{
System.out.println("多线程启动了");
}).start();
}
}
执行结果:
Lambda表达式的使用前提
- 有一个接口
- 接口中有且仅有一一个抽象方法
一个栗子:
Fly接口:
package Lambda.FlyableDemo;
public interface Flyable {
void fly(String s);
}
package Lambda.FlyableDemo;
public class FlyableDemo {
public static void main(String[] args) {
//匿名内部类调用useFlyable方法
useFlyable(new Flyable() {
@Override
public void fly(String s) {
System.out.println(s);
System.out.println("飞机自驾游");
}
});
}
private static void useFlyable(Flyable f){
f.fly("风和日丽,晴空万里");
}
}
如何理解这个匿名内部类呢?
这里调用useFlyable方法,传入的参数要求是Flyable接口,这个接口是直接new出来的,但是接口怎么可以直接new呢,因为下面是直接override了,相当于把1接口实现与2对象创建,3对象调用方法融合为了一步。
因为是调用的useFlyable方法,所以还要完成useflyable中的内容,也就是f.fly(“风和日丽,晴空万里”);这里的fly已经被重写成了:
public void fly(String s) {
System.out.println(s);
System.out.println("飞机自驾游");
}
所以输出就是:
风和日丽,晴空万里
飞机自驾游
补充完了之前学过的匿名内部类,现在再看看如何使用lambda表达式,调用useFlyable方法。
lambda方式:
//lambda方式
public class FlyableDemo {
public static void main(String[] args) {
useFlyable((String s)->{
System.out.println(s);
System.out.println("飞机自驾游");
});
}
private static void useFlyable(Flyable f){
f.fly("风和日丽,晴空万里");
}
这里可能就会有疑问了:
明明useFlyable(Flyable f)要求传入的参数是Flyable接口,但是为何这里却是传入了String s作为参数呢?
这样理解:
在lambda表达式中()理解为接口,()中的参数就是这个接口需要传入的参数,{}中的内容是这个接口中需要执行的方法,不需要使用override进行重写。
带参数和返回值的lambda
AddableDemo主函数
package Lambda.AddableDemo;
public class AddableDemo {
public static void main(String[] args) {
useAddable((int x,int y)->{
return x+y;
});
}
public static void useAddable(Addable a){
int sum=a.add(10,20);
System.out.println(sum);
}
}
Addable接口
package Lambda.AddableDemo;
public interface Addable {
int add(int i, int i1);
}
Lambda表达式的省略模式
①匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
Lambda:只能是接口
抽象类与具体类都报错了。
②如果接口中有且仅有一个抽象方法, 可以使用Lambda表达式,也可以使用匿名内部类
如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
这个是之前对Lambda使用条件的限制
③