Java 8 引入了函数式接口的概念,这是 Lambda 表达式的基础。函数式接口是一个只有一个抽象方法的接口,可以有多个默认方法(使用 default 关键字)和静态方法,但是只能有一个抽象方法。Lambda 表达式可以被用作函数式接口的实例。
Java 8 中引入了很多内置的函数式接口,如 Function、Predicate、Consumer 等,使得 Lambda 表达式的使用更加便捷。同时,开发者也可以自定义函数式接口,用于特定的场景。
函数式接口的定义非常简单,只需要定义一个接口,并且只包含一个抽象方法。例如:
@FunctionalInterface public interface MyFunctionalInterface { void sayHello(String name); }
函数式接口允许接口带有一个或多个默认方法,例如:
@FunctionalInterface public interface MyFunctionalInterface { // 抽象方法 void sayHello(String name); // 默认方法 default void sayHi() { System.out.println("default method"); } }
还可以带有一个或多个静态方法,例如:
@FunctionalInterface public interface MyFunctionalInterface { // 抽象方法 void sayHello(String name); // 默认方法 default void sayHi() { System.out.println("default method"); } // 静态方法 static void sayBye() { System.out.println("static method"); } }
注意:@FunctionalInterface 注解是可选的,但是推荐添加。如果一个接口被这个注解标记,但是却不满足函数式接口的条件(即只有一个抽象方法),那么编译器会报错。
下面是一个使用函数式接口和 Lambda 表达式的示例:
package com.hxstrive.jdk8.function_interface; /** * 函数式接口定义 * @author hxstrive.com */ public class FunctionInterfaceDemo1 { // 自定义函数式接口 @FunctionalInterface public interface MyFunctionalInterface { // 抽象方法 void sayHello(String name); } public static void main(String[] args) { // 使用 Lambda 表达式创建函数式接口的实例 MyFunctionalInterface myFunctionalInterface = System.out::println; // 调用实例 myFunctionalInterface.sayHello("Hello, World!"); } //输出: //Hello, World! }
或者
package com.hxstrive.jdk8.function_interface; /** * 函数式接口定义 * @author hxstrive.com */ public class FunctionInterfaceDemo2 { // 自定义函数式接口 @FunctionalInterface public interface MyFunctionalInterface { // 抽象方法 void sayHello(String name); // 默认方法 default void sayHi() { System.out.println("default method"); } } public static void main(String[] args) { // 使用 Lambda 表达式创建函数式接口的实例 MyFunctionalInterface myFunctionalInterface = System.out::println; // 调用实例 myFunctionalInterface.sayHello("Hello, World!"); myFunctionalInterface.sayHi(); } //输出: //Hello, World! //default method }
或者
package com.hxstrive.jdk8.function_interface; /** * 函数式接口定义 * @author hxstrive.com */ public class FunctionInterfaceDemo3 { // 自定义函数式接口 @FunctionalInterface public interface MyFunctionalInterface { // 抽象方法 void sayHello(String name); // 默认方法 default void sayHi() { System.out.println("default method"); } // 静态方法 static void sayBye() { System.out.println("static method"); } } public static void main(String[] args) { // 使用 Lambda 表达式创建函数式接口的实例 MyFunctionalInterface myFunctionalInterface = System.out::println; // 调用实例方法 myFunctionalInterface.sayHello("Hello, World!"); myFunctionalInterface.sayHi(); // 调用静态方法 FunctionInterfaceDemo3.MyFunctionalInterface.sayBye(); } //结果: //Hello, World! //default method //static method }
上面三个实例均使用了自定义的函数式接口 MyFunctionalInterface。其实,Java8 为了方便我们开发,提供了多个内置函数接口,如下:
Consumer<T> 接口表示接受一个输入参数并且不返回结果的操作。它常用于表示消费行为,比如输出信息到控制台或者修改某个对象的状态。
Supplier<T> 接口表示一个无参数的方法,并返回一个结果。它通常用于创建或提供数据。
Function<T,R> 接口表示接受一个参数并返回结果的方法。它用于转换一个类型的值到另一个类型的值。
Predicate<T> 接口表示接受一个参数并返回布尔值的函数。它常用于条件测试。
UnaryOperator<T> 接口表示接受一个与返回类型相同的参数,并返回该类型结果的函数。它是 Function<T, T> 的一个特殊形式。
BinaryOperator<T> 接口表示接受两个相同类型的参数,并返回相同类型结果的函数。它是 Function<T, U> 的一个特殊形式,其中 U 和 T 是相同的类型。
关于这些内置函数式接口的详细用法,将在后续文章介绍。