语法规则
(参数列表) -> {
代码体;
}
- -> 为Lambda操作符或箭头操作符
- -> 的左边为lambda形参列表,对应重写接口中抽象方法的形参列表
- -> 的右边为lambda体,对应接口实现类重写方法的方法体
- 注意:
- 方法的参数或局部变量类型为接口才能使用 Lambda 表达式。
- Lambda 表达式只能用于只有一个抽象方法的接口。
- 对于自定义接口,如果要保证该接口中的抽象方法只有一个的话,可以使用注解
@FunctionalInterface
,被该注解修饰的接口只能声明一个抽象方法。
import java.util.Arrays;
import java.util.Comparator;
public class LambdaTest {
private static class Person {
String name;
int age;
int height;
public Person(String name, int age, int height) {
this.name = name;
this.age = age;
this.height = height;
}
}
public static void main(String[] args) {
Person[] people = new Person[100];
// 使用 Comparator 接口的匿名内部实现类
Arrays.sort(people, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
if (o1.age == o2.age) return o1.height - o2.height;
return o1.age - o2.age;
}
});
}
}
import java.util.Arrays;
public class LambdaTest {
private static class Person {
String name;
int age;
int height;
public Person(String name, int age, int height) {
this.name = name;
this.age = age;
this.height = height;
}
}
public static void main(String[] args) {
Person[] people = new Person[100];
// 使用 Lambda 表达式
Arrays.sort(people, (Person o1, Person o2) -> {
if (o1.age == o2.age) return o1.height - o2.height;
return o1.age - o2.age;
});
}
}
Lambda 表达式的简化写法
()
内的参数类型可以省略,可以由编译器推断得出(类型推断)public static void main(String[] args) { Person[] people = new Person[100]; // Lambda 表达式,省略参数类型 Arrays.sort(people, (o1, o2) -> { if (o1.age == o2.age) return o1.height - o2.height; return o1.age - o2.age; }); }
()
内的参数只有一个,()
可以省略。
public class LambdaTest {
public static void main(String[] args) {
// 调用 goShow 方法
// 该方法需要传递接口 MyInterface 的实现类实例
// goShow 方法中调用 MyInterface 实现类实例的 show 方法
// MyInterface 实现类实例的 show 方法为
// content -> {
// System.out.println(content);
// }
goShow(content -> {
System.out.println(content);
});
}
private static void goShow(MyInterface myInterface) {
myInterface.show("hello world");
}
}
3.{}
内只有一个语句,可以省略 {}
return
关键字以及语句 ;
。如果将 {}
省略,则 return 也一定要省略,若 return 不省略,则 {}
要保留
public static void main(String[] args) {
Person[] people = new Person[100];
// 省略 参数类型 以及 {} 、return 关键字 、语句 ;
Arrays.sort(people, (o1, o2) -> o1.age - o2.age);
}
Lambda 表达式和匿名内部类的对比
所需类型不一样:
匿名内部类的类型可以是类、抽象类、接口。
Lambda 表达式需要的类型必须是接口。
抽象方法的数量不一样:
匿名内部类中抽象方法的数量是任意的。
Lambda 表达式所需的接口中只能有一个抽象方法。
实现原理不同:
匿名内部类会在编译后生成一个对应的 class(Java 类、.class 文件)。
Lambda 表达式是在程序运行时动态生成 class。
会在使用 Lambda 表达式的类中新增一个静态方法,该静态方法中的代码体为 Lambda 表达式中的代码体。
同时会在程序运行时动态生成一个 class 类,该类继承了接口并实现了接口中的抽象方法,在实现的抽象方法中调用在使用 Lambda 表达式的类中新增的静态方法。
lambda 表达式的本质
- lambda表达式充当了接口的实现类对象
- lambda表达式也可以认为是一个匿名函数