Java 函数式接口

更新于 2025-12-25

Jakob Jenkov 2021-03-08

“Java 函数式接口”这一术语是在 Java 8 中引入的。Java 中的函数式接口是指仅包含一个抽象(未实现)方法的接口。函数式接口除了这个唯一的未实现方法外,还可以包含具有具体实现的默认方法(default methods)和静态方法(static methods)。

以下是一个 Java 函数式接口的示例:

public interface MyFunctionalInterface {
    public void execute();
}

上述接口之所以被视为函数式接口,是因为它只包含一个方法,并且该方法没有实现。通常,Java 接口中的方法不包含实现,但可以通过默认方法或静态方法提供实现。下面是一个包含部分方法实现的函数式接口示例:

public interface MyFunctionalInterface2 {
    public void execute();

    public default void print(String text) {
        System.out.println(text);
    }

    public static void print(String text, PrintWriter writer) throws IOException {
        writer.write(text);
    }
}

尽管该接口中包含了默认方法和静态方法,但由于它仍然只有一个未实现的方法(即 execute()),因此它依然是一个合法的函数式接口。


函数式接口可以用 Lambda 表达式实现

Java 函数式接口可以使用 Lambda 表达式 来实现。下面的例子展示了如何用 Lambda 表达式实现前面定义的 MyFunctionalInterface 接口:

MyFunctionalInterface lambda = () -> {
    System.out.println("Executing...");
};

Java Lambda 表达式用于实现接口中的单个方法。为了让编译器知道 Lambda 表达式实现的是哪个方法,该接口必须仅包含一个未实现的方法——也就是说,它必须是一个函数式接口。

本文不会深入讲解 Lambda 表达式的细节。如需了解更多信息,请点击本节开头的链接。


Java 内置的函数式接口

Java 提供了一组为常见场景设计的内置函数式接口,因此你无需为每个小用途都自己定义新的函数式接口。以下将介绍一些 Java 中常用的内置函数式接口。

Function

Java 的 Function 接口(java.util.function.Function)是 Java 中最核心的函数式接口之一。它表示一个接收单个参数并返回单个结果的函数。其定义如下:

public interface Function<T, R> {
    public R apply(T parameter);
}

实际上,Function 接口中还包含一些额外的方法,但这些方法都有默认实现,因此在实现 Function 接口时,你只需实现 apply() 方法即可。

下面是一个 Function 的实现示例:

public class AddThree implements Function<Long, Long> {
    @Override
    public Long apply(Long aLong) {
        return aLong + 3;
    }
}

该实现接收一个 Long 类型参数,并返回加 3 后的结果。使用方式如下:

Function<Long, Long> adder = new AddThree();
Long result = adder.apply((long) 4);
System.out.println("result = " + result); // 输出: result = 7

你也可以使用 Lambda 表达式来实现 Function 接口:

Function<Long, Long> adder = (value) -> value + 3;
Long resultLambda = adder.apply((long) 8);
System.out.println("resultLambda = " + resultLambda); // 输出: resultLambda = 11

可以看到,使用 Lambda 表达式将实现逻辑直接内联到变量声明中,代码更简洁,也更直观。


Predicate

Java 的 Predicate 接口(java.util.function.Predicate)表示一个接收单个参数并返回 boolean 值的函数。其定义如下:

public interface Predicate<T> {
    boolean test(T t);
}

Predicate 接口也包含其他默认或静态方法,但你只需关注 test() 方法。

使用类实现 Predicate 的示例如下:

public class CheckForNull implements Predicate<Object> {
    @Override
    public boolean test(Object o) {
        return o != null;
    }
}

也可以使用 Lambda 表达式实现:

Predicate<Object> predicate = (value) -> value != null;

该 Lambda 表达式与上面的类实现功能完全相同。


UnaryOperator

UnaryOperator 是一个特殊的 Function,其输入和输出类型相同。它表示对单个参数进行操作,并返回同类型的值。

示例:

UnaryOperator<Person> unaryOperator = (person) -> {
    person.name = "New Name";
    return person;
};

UnaryOperator 常用于在函数式流处理链中对对象进行修改并返回。


BinaryOperator

BinaryOperator 表示一个接收两个同类型参数、并返回一个同类型结果的操作。常用于求和、相减、相乘等操作。

示例:

BinaryOperator<MyValue> binaryOperator = (value1, value2) -> {
    value1.add(value2);
    return value1;
};

Supplier

Supplier 表示一个不接收参数、但提供(生成)某个值的函数。也可以看作是一个工厂接口。

示例:

Supplier<Integer> supplier = () -> new Integer((int) (Math.random() * 1000D));

Supplier 每次调用都会返回一个 0 到 999 之间的随机整数。


Consumer

Consumer 表示一个接收参数但不返回任何结果的操作。典型用途包括打印、写入文件或网络等。

示例:

Consumer<Integer> consumer = (value) -> System.out.println(value);

Consumer 会将传入的整数值打印到控制台。