Java中函数式接口的核心是仅含一个抽象方法的接口,配合@FunctionalInterface注解;它为Lambda表达式提供类型支撑,而真正简化排序与过滤的是Lambda结合Stream API,函数式接口是二者协同的契约基础。

一、如何正确定义函数式接口
必须满足:仅含一个未被重写的抽象方法(默认方法、静态方法、Object 继承方法不计)。
示例:
@FunctionalInterface
public interface IntPredicate {
boolean test(int value); // ✅ 唯一抽象方法
// ✅ 允许默认方法
default boolean negate() {
return !test(0);
}
// ✅ 允许静态方法
static IntPredicate alwaysTrue() {
return x -> true;
}
}
如果多写一个抽象方法,编译报错:Unexpected @FunctionalInterface annotation。
二、四大内置函数式接口是实际主力
不用自己造轮子。Java 8 提供了 `java.util.function` 包中常用接口,覆盖绝大多数场景:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- Predicate<T>:输入 T,返回 boolean → 用于 filter
- Function<T, R>:输入 T,输出 R → 用于 map
- Comparator<T>:输入两个 T,返回 int → 用于 sorted
- Consumer<T>:输入 T,无返回 → 用于 forEach
它们都是标准函数式接口,可直接接收 Lambda,无需额外定义。
三、用在集合排序与过滤中的典型写法
关键不是“接口怎么定义”,而是“怎么用接口类型让 Lambda 被正确接受”。看两个真实例子:
✅ 过滤(用 Predicate)
List<User> users = ...;
// filter 方法参数类型是 Predicate<User>
List<User> adults = users.stream()
.filter(user -> user.getAge() >= 18) // 自动匹配为 Predicate<User>
.collect(Collectors.toList());
✅ 排序(用 Comparator)
// sorted() 方法参数是 Comparator<String>
List<String> names = Arrays.asList("zhang", "li", "wang");
names.sort((s1, s2) -> s1.compareTo(s2)); // 自动匹配为 Comparator<String>
// 多字段排序(仍基于 Comparator)
list.sort(Comparator.comparing(User::getAge)
.thenComparing(User::getName));
这里 `(s1,s2) -> ...` 能被识别,正是因为 `Comparator` 是函数式接口,编译器知道该把 Lambda 绑定到它的 `compare` 方法上。

















