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 是相同的类型。
关于这些内置函数式接口的详细用法,将在后续文章介绍。