Java——Lambda表达式
一、Lambda表达式格式
(形式参数) -> {代码块}
二、Lambda表达式的使用前提
- 有一个接口
- 接口中有且仅有一个抽象方法
三、Lambda表达式练习
1、抽象方法无参无返回值
① 要求
- 定义一个接口(Eatable),里边定义一个抽象方法:void eat()
- 定义一个测试类(EatableDemo),在测试类中提供两个方法
useEatable(Eatable e)
主方法:主方法中调用useEatable方法
② 代码实现
代码实现时使用三种方式:
- 创建类对象
- 匿名内部类
- Lambda表达式
Eatable接口
public interface Eatable {
void eat();
}
接口的实现类
public class EatableImpl implements Eatable {
@Override
public void eat() {
System.out.println("吃");
}
}
EatableDemo测试类
public class EatableDemo {
public static void main(String[] args) {
Eatable e = new EatableImpl();
useEatable(e);
//匿名内部类
useEatable(new Eatable() {
@Override
public void eat() {
System.out.println("吃");
}
});
//Lambda表达式
useEatable(() -> {
System.out.println("吃");
});
}
private static void useEatable(Eatable e) {
e.eat();
}
}
2、抽象方法带参无返回值
① 要求
- 定义一个接口(Flyable),里边定义一个抽象方法:void fly(String s)
- 定义一个测试类(FlyableDemo),在测试类中提供两个方法
useFlyable(Eatable e)
主方法:主方法中调用useFlyable方法
② 代码实现
代码实现时使用2种方式:
- 匿名内部类
- Lambda表达式
Flyable接口
public interface Flyable {
void fly(String s);
}
FlyableDemo测试类
public class FlyableDemo {
public static void main(String[] args) {
//匿名内部类
useFlyable(new Flyable() {
@Override
public void fly(String s) {
System.out.println(s);
System.out.println("飞机自驾游");
}
});
System.out.println("--------------");
//Lambda
useFlyable((String s)->{
System.out.println(s);
System.out.println("飞机自驾游");
});
}
private static void useFlyable(Flyable f){
f.fly("风和日丽");
}
}
3、抽象方法带参带返回值
① 要求
- 定义一个接口(Addable),里边定义一个抽象方法:int add(int x, int y)
- 定义一个测试类(AddableDemo),在测试类中提供两个方法
useAddable(Eatable e)
主方法:主方法中调用useAddable方法
② 代码实现
代码实现时使用2种方式:
- 匿名内部类
- Lambda表达式
Addable接口
public interface Addable {
int add(int x, int y);
}
AddableDemo测试类
public class AddableDemo {
public static void main(String[] args) {
//匿名内部类
useAddable(new Addable() {
@Override
public int add(int x, int y) {
return x+y;
}
});
System.out.println("-----------------");
//Lambda表达式
useAddable((int x,int y)->{
return x+y;
});
}
public static void useAddable(Addable a){
int sum = a.add(2, 5);
System.out.println(sum);
}
}
四、Lambda表达式的省略模式
1、参数类型可以省略。但是有多个参数的情况下,不能只省略一个。要么不省略,要么全部省略
useAddable((x, y) -> {
return x + y;
});
2、如果参数有且只有一个,参数的小括号可以省略
useFlyable(s -> {
System.out.println(s);
});
3、 如果代码块的语句只有一条,可以省略大括号和分号。如果有return,return也要省略
useFlyable(s -> System.out.println(s));
useAddable((x, y) -> x + y);
五、Lambda表达式的注意事项
1、使用Lambda必须要有接口,并且接口中有且只有一个抽象方法
2、必须有上下文环境,才能推导出Lambda对应的接口
下述代码会报错:
()-> System.out.println("Lambda表达式");
正确方式:
a.根据局部变量的赋值,才能推导出Lambda对应的接口
Runnable r =()-> System.out.println("Lambda表达式");
new Thread(r).start();
b.根据调用方法的参数得知Lambda对应的接口
new Thread(()-> System.out.println("Lambda表达式")).start();
六、Lambda表达式和匿名内部类的区别
1、所需类型不同
- 匿名内部类:可以是接口、抽象类、具体类
- Lambda表达式:只能是接口
2、使用限制不同
- 如果接口中有且只有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
- 如果接口中多于一个抽象方法,只能使用匿名内部类,不能使用Lambda表达式
3、实现原理不同
- 匿名内部类:编译之后,产生一个单独的.class字节码文件
- Lambda表达式:编译之后,没有一个单独的.class字节码文件,对应的字节码会在运行的时候动态生成