概述:FunctionInterface/函数式接口
简介
-
函数式接口是指只包含一个抽象方法的接口,可以使用
Lambda
表达式来创建该接口的实例。 -
@FunctionalInterface
注解是Java Lang
包中的一个注解,用于标识一个接口是函数式接口。 -
@FunctionalInterface
注解的作用:
- 编译时检查:
@FunctionalInterface
注解会在编译时检查标注的接口是否符合函数式接口的定义,即是否只有一个抽象方法。如果不符合,编译器会报错,提醒开发者修正。- Lambda 表达式支持:函数式接口的存在主要是为了支持 Lambda 表达式,通过 Lambda 表达式可以简化代码,提高代码的可读性。
- 事实上,即使没有加
@FunctionalInterface
注解,只要符合函数式接口的定义就是函数式接口。
在 Spring Boot 框架中,经常使用的
CommandLineRunner
、ApplicationRunner
等等都是函数式接口。
函数式接口的使用场景
回调函数(Callback Functions)
- 在一些异步操作或模板方法中,我们可以使用函数式接口来传递回调函数,从而实现定制化的操作。
事件监听器(Event Listeners)
-
通过函数式接口可以定义事件监听器,用于监听特定事件的发生并执行相应的处理逻辑。
-
在Spring boot 框架中,事件监听器通常用于处理应用程序内部的事件,如应用启动、关闭、Bean初始化完成等。
Stream API
-
在Java 8及以上版本中,引入了Stream API,可以通过函数式接口来操作集合数据。
-
在Spring应用中,同样可以利用Stream API对集合数据进行处理、过滤、转换等操作,使得代码更为简洁和可读。
以上就是函数式接口的整理,函数式接口是指只包含一个抽象方法的接口。
案例实践
案例1 MyFunctionalInterface 的简单使用
MyFunctionalInterface
@FunctionalInterface
interface MyFunctionalInterface {void myMethod();
}
FunctionalInterfaceTest
public class FunctionalInterfaceTest {public static void main(String[] args) {// 使用 Lambda 表达式创建 MyFunctionalInterface 的实例MyFunctionalInterface myFunctionalInterface = () -> System.out.println("Hello, Functional Interface!");// 调用接口的抽象方法myFunctionalInterface.myMethod();}
}
out
Hello, Functional Interface!
MyFunctionalInterface 使用 @FunctionalInterface 注解标识,接口中确保只有一个抽象方法。
在测试类的 main 方法中,我们使用 Lambda 表达式调用了函数式接口
案例2 Calculator
Calculator
@FunctionalInterface
public interface Calculator {int calculate(int a, int b);
}
FunctionalInterfaceTest
public class FunctionalInterfaceTest {public static void main(String[] args) {// 使用 lambda 表达式实现加法Calculator addition = (a, b) -> a + b;System.out.println("3 + 5 = " + addition.calculate(3, 5)); // 输出 8// 使用 lambda 表达式实现减法Calculator subtraction = (a, b) -> a - b;System.out.println("7 - 2 = " + subtraction.calculate(7, 2)); // 输出 5// 使用 lambda 表达式实现乘法Calculator multiplication = (a, b) -> a * b;System.out.println("4 * 6 = " + multiplication.calculate(4, 6)); // 输出 24}
}
out
3 + 5 = 8
7 - 2 = 5
4 * 6 = 24
- 案例分析
Calculator 是一个函数式接口,只包含一个抽象方法 calculate
通过 lambda 表达式分别实现了加法、减法和乘法,并在 main 方法中进行了调用
案例3 使用java.util.function
包中的函数式接口(Predicate/Function/Consumer)
- 结合使用
Predicate
、Function
和Consumer
等接口来进行数据处理和过滤
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;public class FunctionalInterfaceTest {public static void main(String[] args) {List<String> names = Arrays.asList("John", "Doe", "Jane", "Smith", "Alice");// 使用 Predicate 过滤出长度大于等于4的字符串Predicate<String> filterPredicate = str -> str.length() >= 4;// 使用 Function 将字符串转换为大写Function<String, String> toUpperCaseFunction = String::toUpperCase;// 使用 Consumer 输出字符串Consumer<String> printConsumer = System.out::println;// 结合 Predicate、Function 和 Consumer 进行数据处理和输出names.stream().filter(filterPredicate).map(toUpperCaseFunction).forEach(printConsumer);}
}
out
JOHN
JANE
SMITH
ALICE
- 案例分析
使用了 Predicate 进行字符串长度的过滤,然后使用 Function 将过滤后的字符串转换为大写,最后使用 Consumer 输出结果
X 参考文献
- 理解函数式接口 @FunctionalInterface - Zhihu