目录
1. 概念
1.1. 为什么要引入Lambda表达式
简化实现函数式接口(Functional Interface,
@FunctionalInterface
)
函数式接口: 有且只有一个抽象方法,但可以有多个非抽象方法的接口。
- 结构:
- 注解:
@FunctionalInterface
,可以不加此注解,只要符合只有一个抽象方法的定义,那编译器也会识别为一个函数式接口; - 一个抽象方法:必须要有,且只能有一个;
- 一个或多个非抽象方法。
@FunctionalInterface public interface GreetingService { // 抽象方法 String greet(String name); // 默认方法(非抽象) default void printGreeting(String name) { String greeting = greet(name); System.out.println("Hello, " + greeting + "!"); } // 静态方法(非抽象) static GreetingService createDefaultGreetingService() { return (name) -> "Hello, " + name; } }
- 注解:
- 作用:
简化匿名内部类
我现在有一个函数式接口:
public interface Authorization {
int calculate(int a, int b);
}
我需要使用这个接口中的calculate方法,用来实现a+b:
public class Addition implements Authorization{
@Override
public int calculate(int a, int b) {
return a + b;
}
}
public static void main(String[] args) {
Authorization auth = new Addition();
int calculate = auth.calculate(1, 2);
System.out.println(calculate);// return 3
}
如果我使用匿名内部类的写法,那就是这样的:
public static void main(String[] args) {
Authorization auth = new Authorization() {
@Override
public int calculate(int a, int b) {
return a + b;
}
};
System.out.println(auth.calculate(1, 2));// return 3
}
如果我用Lambda表达式的写法,那就是这样:
public static void main(String[] args) {
// 也可以不声明参数类型 Authorization authorization = (a, b) -> a + b;
Authorization authorization = (int a, int b) -> a + b;
authorization.calculate(1, 2);// return 3
}
美化代码
1.2. 概念说明
抽象方法:
- 概念:仅有方法签名(包括返回类型、方法名和参数列表)而没有具体实现(方法体)的成员方法,必须在抽象类或接口中声明,并要求子类或实现类提供其实现。
- 识别:在抽象类中使用
abstract
来修饰的方法,以及在接口中没有方法体的方法(接口中的方法都默认是抽象方法,不过在JDK8引入了default
方法,此方法不是抽象的)。 - 案例:
-
抽象类中的抽象方法
public abstract class Shape { // 非抽象方法(已实现) public String getDescription() { return "This is an abstract shape."; } // 抽象方法(未实现,子类必须提供实现) public abstract double calculateArea(); // 可选:其他成员变量、构造方法、非抽象方法等 }
-
接口
public interface MyInterface { // 抽象方法 void abstractMethod(); // 默认方法(非抽象) default void nonAbstractMethod() { System.out.println("This is a default method implementation."); } }
-
为什么函数式接口是Lambda表达式的基石?
由于Lambda表达式本身是一种简洁、轻量级的匿名函数形式,它没有名称,也没有明确的类定义。为了让Lambda表达式能够与现有的面向对象结构兼容,Java要求Lambda表达式必须能够被赋值给一个类型明确的对象。函数式接口恰好提供了这种类型,它的单个抽象方法定义了Lambda表达式可以具有的行为签名。通过将Lambda表达式赋值给函数式接口的实例,Lambda表达式获得了类型,从而能够在Java代码中被安全地使用。
简化行为参数化
函数式接口使得方法可以接受行为作为参数。这意味着方法可以要求调用者传递一个特定操作的实现(如一个计算规则、一个筛选条件、一个转换逻辑等),而不是具体的业务数据。这极大地提升了代码的灵活性和可重用性。
支持函数式编程风格
使用Lambda表达式、函数式接口、Stream API等工具来编写简洁、声明式、无副作用的代码。
-
使用Lambda表达式
public static void main(String[] args) { List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); // 使用Lambda表达式过滤长度大于3的名字 names.stream() .filter(name -> name.length() > 3) .forEach(System.out::println); // 输出:Bob, Charlie }
-
使用函数式接口作为方法参数
public class FunctionInterfaceExample { public static void main(String[