Java中函数式接口的定义及用法
Java 8 引入了函数式接口(Functional Interface)。函数式接口是指只有一个抽象方法的接口,它可以被用作 Lambda 表达式的类型。在 Java 中,Lambda 表达式被定义为一种函数式接口的实例类型。
定义函数式接口
在 Java 中,我们可以使用 @FunctionalInterface 注解来标记一个接口是一个函数式接口。这个注解不是必须的,但它可以确保接口只有一个抽象方法。如果我们不小心在一个函数式接口中添加了第二个抽象方法,编译器就会报错。
例如,下面这个接口就是一个函数式接口:
@FunctionalInterface
public interface MyFunction {
int myMethod(int a, int b);
}
这个接口只有一个抽象方法 myMethod,因此它被标记为一个函数式接口。
使用函数式接口
函数式接口可以用于与 Lambda 表达式一起使用。Lambda 表达式就是一个匿名函数,其类型是一个函数式接口。
例如,我们可以使用上面定义的 MyFunction 接口来创建一个 Lambda 表达式:
MyFunction add = (a, b) -> a + b;
这个 Lambda 表达式实现了 MyFunction 接口中的 一个抽象方法 myMethod。它接受两个 int 类型的参数 a 和 b,并返回它们的和。
我们可以调用 Lambda 表达式来计算两个数字的和:
int result = add.myMethod(2, 3); System.out.println(result); // 输出 5
在这个例子中,我们首先定义了一个 MyFunction 类型的变量 add,并通过 Lambda 表达式给它赋值。然后,我们调用 add.myMethod(2, 3),得到计算结果 5。
Java 8 API 中的函数式接口
Java 8 在 java.util.function 包中提供了一些常用的函数式接口。这些接口可以在 Lambda 表达式中使用,从而使代码更加简洁和易读。
以下是一些常用的函数式接口:
1. Consumer:接受一个参数,不返回任何值。
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
例如,我们可以使用 Consumer 接口来打印一些信息:
Consumer<String> print = System.out::println;
print.accept("Hello, world!");
这个 Lambda 表达式接受一个字符串参数,然后将它打印到控制台上。
2. Function:接受一个参数,并返回一个值。
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
例如,我们可以使用 Function 接口来计算一个字符串的长度:
Function<String, Integer> length = String::length;
int len = length.apply("Java");
System.out.println(len); // 输出 4
这个 Lambda 表达式接受一个字符串参数,然后返回这个字符串的长度。
3. Predicate:接受一个参数,并返回一个 boolean 值。
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
例如,我们可以使用 Predicate 接口来判断一个字符串是否为空:
Predicate<String> isEmpty = String::isEmpty;
boolean result = isEmpty.test("");
System.out.println(result); // 输出 true
这个 Lambda 表达式接受一个字符串参数,然后返回它是否为空的 boolean 值。
总结
函数式接口是 Java 8 提供的一种新特性,它可以让我们更加方便地使用 Lambda 表达式。在使用函数式接口时,我们可以通过 @FunctionalInterface 注解来标记一个接口是一个函数式接口,从而避免在接口中添加多个抽象方法。Java 8 还提供了一些常用的函数式接口,如 Consumer、Function 和 Predicate 等,通过它们,我们可以更加方便地实现一些常见的功能。
