函数式接口的定义
函数式接口可以通过 @FunctionalInterface
注解进行标注,这样编译器会检查接口是否符合函数式接口的定义(即只包含一个抽象方法)。即使不使用这个注解,满足条件的接口也依然是函数式接口。
一个简单的函数式接口示例:
@FunctionalInterface public interface MyFunctionalInterface {
void doSomething();
}
函数式接口作为参数
在使用 Lambda 表达式或方法引用时,经常会将函数式接口作为方法的参数。这允许开发者通过简洁的语法来传递行为。
例如,定义一个接受函数式接口的方法:
public class FunctionalInterfaceExample {
public static void execute(MyFunctionalInterface action) {
action.doSomething();
}
public static void main(String[] args) {
// 使用Lambda表达式作为参数
execute(() -> System.out.println("Doing something with Lambda!")); // 使用方法引用作为参数
execute(FunctionalInterfaceExample::someMethod);
}
public static void someMethod() {
System.out.println("Doing something with method reference!");
}
}
在上面的例子中,execute
方法接受一个 MyFunctionalInterface
类型的参数。我们可以传递一个 Lambda 表达式或方法引用作为参数。
常见的函数式接口
Java 8 及以后的版本在 java.util.function
包中提供了许多常见的函数式接口,例如:
Function<T, R>
: 接受一个参数,返回一个结果。Predicate<T>
: 接受一个参数,返回一个布尔值。Consumer<T>
: 接受一个参数,不返回结果。Supplier<T>
: 不接受参数,返回一个结果。UnaryOperator<T>
: 接受一个参数,返回与该参数相同类型的结果。BinaryOperator<T>
: 接受两个相同类型的参数,返回与该参数相同类型的结果。
这些接口使得在使用 Lambda 表达式时更加方便。例如:
import java.util.function.*;
public class FunctionalInterfaceDemo {
public static void main(String[] args) {
// 使用 Predicate 函数式接口
Predicate<String> isLongerThan5 = s -> s.length() > 5;
System.out.println(isLongerThan5.test("Hello")); // false
System.out.println(isLongerThan5.test("Hello, World!")); // true
// 使用 Function 函数式接口
Function<String, Integer> stringLength = String::length;
System.out.println(stringLength.apply("Hello")); // 5
// 使用 Consumer 函数式接口
Consumer<String> print = System.out::println;
print.accept("Hello, World!");
// 使用 Supplier 函数式接口
Supplier<String> stringSupplier = () -> "Hello from Supplier";
System.out.println(stringSupplier.get());
}
}
总结
函数式接口是 Java 8 引入的一种重要特性,支持 Lambda 表达式和方法引用,从而简化代码的编写,提高代码的可读性和灵活性。通过函数式接口,Java 开发者可以轻松传递行为,并在许多标准库和框架中广泛使用。