一、核心函数式接口概览
Java 8 引入了四个核心函数式接口,位于 java.util.function 包中:
classDiagram
class Function{
+R apply(T t)
}
class Consumer{
+void accept(T t)
}
class Supplier{
+T get()
}
class Predicate{
+boolean test(T t)
}
![图片[1]_Java 8 四大函数式接口详解_知途无界](https://zhituwujie.com/wp-content/uploads/2025/08/d2b5ca33bd20250831111756.png)
二、Function 接口详解
2.1 基本定义
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
// 默认方法
default <V> Function<V, R> compose(Function<? super V, ? extends T> before)
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after)
static <T> Function<T, T> identity()
}
2.2 使用示例
// 示例1:字符串转整数
Function<String, Integer> strToInt = Integer::parseInt;
int num = strToInt.apply("123"); // 123
// 示例2:组合函数
Function<Integer, Integer> square = x -> x * x;
Function<Integer, String> squareToString = square.andThen(String::valueOf);
String result = squareToString.apply(5); // "25"
// 示例3:方法引用
Function<String, String> toUpperCase = String::toUpperCase;
String upper = toUpperCase.apply("hello"); // "HELLO"
2.3 变种接口
| 接口 | 方法签名 | 特殊说明 |
|---|---|---|
| IntFunction | R apply(int value) | 接收int参数 |
| DoubleFunction | R apply(double value) | 接收double参数 |
| ToIntFunction | int applyAsInt(T value) | 返回int结果 |
| BiFunction<T,U,R> | R apply(T t, U u) | 接收两个参数 |
三、Consumer 接口详解
3.1 基本定义
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
// 默认方法
default Consumer<T> andThen(Consumer<? super T> after)
}
3.2 使用示例
// 示例1:打印元素
Consumer<String> printer = System.out::println;
printer.accept("Hello World"); // 输出 Hello World
// 示例2:集合遍历
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(printer);
// 示例3:组合消费者
Consumer<String> logger = s -> System.out.println("Log: " + s);
Consumer<String> combined = printer.andThen(logger);
combined.accept("Test"); // 先打印,再记录日志
3.3 变种接口
| 接口 | 方法签名 | 特殊说明 |
|---|---|---|
| IntConsumer | void accept(int value) | 接收int参数 |
| DoubleConsumer | void accept(double value) | 接收double参数 |
| BiConsumer<T,U> | void accept(T t, U u) | 接收两个参数 |
| ObjIntConsumer | void accept(T t, int value) | 对象+int参数 |
四、Supplier 接口详解
4.1 基本定义
@FunctionalInterface
public interface Supplier<T> {
T get();
}
4.2 使用示例
// 示例1:随机数生成
Supplier<Double> randomSupplier = Math::random;
double random = randomSupplier.get();
// 示例2:对象工厂
Supplier<LocalDate> todaySupplier = LocalDate::now;
LocalDate today = todaySupplier.get();
// 示例3:延迟计算
Supplier<String> expensiveOperation = () -> {
// 模拟耗时操作
try { Thread.sleep(1000); }
catch (InterruptedException e) {}
return "Result";
};
4.3 变种接口
| 接口 | 方法签名 | 特殊说明 |
|---|---|---|
| BooleanSupplier | boolean getAsBoolean() | 返回boolean |
| IntSupplier | int getAsInt() | 返回int |
| LongSupplier | long getAsLong() | 返回long |
| DoubleSupplier | double getAsDouble() | 返回double |
五、Predicate 接口详解
5.1 基本定义
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
// 默认方法
default Predicate<T> and(Predicate<? super T> other)
default Predicate<T> or(Predicate<? super T> other)
default Predicate<T> negate()
static <T> Predicate<T> isEqual(Object targetRef)
}
5.2 使用示例
// 示例1:字符串过滤
Predicate<String> isEmpty = String::isEmpty;
boolean test = isEmpty.test(""); // true
// 示例2:组合谓词
Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isEvenAndPositive = isEven.and(isPositive);
boolean result = isEvenAndPositive.test(4); // true
// 示例3:集合过滤
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream()
.filter(isEven)
.collect(Collectors.toList()); // [2, 4]
5.3 变种接口
| 接口 | 方法签名 | 特殊说明 |
|---|---|---|
| IntPredicate | boolean test(int value) | 接收int参数 |
| LongPredicate | boolean test(long value) | 接收long参数 |
| DoublePredicate | boolean test(double value) | 接收double参数 |
| BiPredicate<T,U> | boolean test(T t, U u) | 接收两个参数 |
六、高级应用场景
6.1 函数组合
// 函数链式操作
Function<Integer, Integer> add = x -> x + 1;
Function<Integer, Integer> multiply = x -> x * 2;
Function<Integer, Integer> combined = add.andThen(multiply);
int result = combined.apply(3); // (3 + 1) * 2 = 8
// 谓词组合
Predicate<String> startsWithA = s -> s.startsWith("A");
Predicate<String> endsWithE = s -> s.endsWith("e");
Predicate<String> startsWithAOrEndsWithE = startsWithA.or(endsWithE);
6.2 方法引用与Lambda
// 静态方法引用
Function<String, Integer> parseInt = Integer::parseInt;
// 实例方法引用
Consumer<String> print = System.out::println;
// 构造方法引用
Supplier<List<String>> listSupplier = ArrayList::new;
// 对象方法引用
Predicate<String> isEmpty = String::isEmpty;
6.3 Stream API 集成
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 使用Predicate过滤
List<String> longNames = names.stream()
.filter(s -> s.length() > 4)
.collect(Collectors.toList());
// 使用Function转换
List<Integer> nameLengths = names.stream()
.map(String::length)
.collect(Collectors.toList());
// 使用Consumer遍历
names.stream().forEach(System.out::println);
七、性能考量
7.1 内存占用比较
| 实现方式 | 内存占用 | 说明 |
|---|---|---|
| 匿名类 | 较高 | 每次调用创建新对象 |
| Lambda | 较低 | 可能共享实例 |
| 方法引用 | 最低 | 通常单例实现 |
7.2 最佳实践
- 优先使用方法引用:更简洁且通常更高效
- 避免复杂Lambda:超过3行的Lambda考虑提取方法
- 重用函数实例:对于常用操作缓存函数对象
- 注意闭包捕获:避免在Lambda中捕获大对象
八、常见问题解答
8.1 接口选择指南
flowchart TD
A[需要返回值?] -->|是| B{参数数量?}
A -->|否| C[Consumer]
B -->|单参数| D[Function]
B -->|无参数| E[Supplier]
B -->|双参数| F[BiFunction]
C --> G{需要条件判断?}
G -->|是| H[Predicate]
G -->|否| I[纯Consumer]
8.2 典型错误案例
// 错误1:修改外部变量
int counter = 0;
names.forEach(s -> counter++); // 编译错误
// 错误2:忽略返回值
Function<String, Integer> parser = Integer::parseInt;
parser.apply("123"); // 返回值被忽略
// 错误3:过度嵌套
Function<Integer, Function<Integer, Integer>> adder = x -> y -> x + y; // 可读性差
8.3 调试技巧
- 打印中间结果:
Function<String, Integer> debugParser = s -> { System.out.println("Parsing: " + s); return Integer.parseInt(s); }; - 使用peek方法:
names.stream() .peek(System.out::println) .filter(s -> s.length() > 3) .forEach(...); - 拆解复杂链式调用:分步调试各函数结果
九、扩展应用示例
9.1 自定义函数式接口
@FunctionalInterface
interface TriFunction<T, U, V, R> {
R apply(T t, U u, V v);
}
// 使用示例
TriFunction<Integer, Integer, Integer, Integer> sumThree =
(a, b, c) -> a + b + c;
int total = sumThree.apply(1, 2, 3); // 6
9.2 高阶函数
// 接收函数作为参数
public static <T, R> List<R> transformList(
List<T> list, Function<T, R> transformer) {
return list.stream()
.map(transformer)
.collect(Collectors.toList());
}
// 返回函数
public static Function<String, String> createPrefixer(String prefix) {
return s -> prefix + s;
}
9.3 函数式设计模式
// 策略模式
public class Validator {
private final Predicate<String> strategy;
public Validator(Predicate<String> strategy) {
this.strategy = strategy;
}
public boolean validate(String input) {
return strategy.test(input);
}
}
// 使用
Validator numberValidator = new Validator(s -> s.matches("\\d+"));
boolean isValid = numberValidator.validate("123"); // true
关键要点总结:
Function用于转换操作,接收T返回RConsumer用于消费操作,无返回值Supplier用于提供数据,无参数有返回值Predicate用于条件判断,返回boolean- Java 8提供了40+个函数式接口变种满足特殊需求
- 合理使用函数组合可以大幅提升代码表达能力
- 在Stream API中函数式接口发挥核心作用
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END

























暂无评论内容