JDK8中内置的函数式接口简介
作为 Lambda 表达式的核心支持基础,JDK 8 内置了大量可直接使用的函数式接口,都位于 java.util.function 包中,常用于 Lambda 表达式 或 函数式编程场景。
以下是较常用的内置函数式接口分类及说明:
一、有入参,有出参
包含有Function系列接口和Operator系列接口,如:Function<T,R>
/ BiFunction<T,U,R>
/ UnaryOperator<T>
/ BinaryOperator<T>
等;
适用于:字段映射、数据清洗、格式化、归约的场景;
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
// 示例
Function<Integer, String> toStr = i -> "value: " + i;
BiConsumer<String, Integer> bc = (s, i) -> System.out.println(s + i);
UnaryOperator<String> toUpper = s -> s.toUpperCase();
BinaryOperator<Integer> sum = (a, b) -> a + b;
二、有入参,无出参
包含有Consumer系列接口,如:Consumer<T>
/ BiConsumer<T,U>
;
适用于:打印日志、存储、修改外部状态;
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
// 示例
Consumer<String> c = s -> System.out.println(s);
BiConsumer<String, Integer> kvConsumer = (k, v) -> System.out.println(k + v);
三、无入参,有出参
主要为Supplier<T>
接口;
适用于:延迟获取/懒加载、缓存、配置加载、对象工厂等场景;
@FunctionalInterface
public interface Supplier<T> {
T get();
}
// 示例
Supplier<String> s = () -> "hello";
四、无入参,无出参,通用任务
function包下没有定义此类接口,可以使用Runnable
和 Callable
接口;
适用于:线程池、异步任务、**定时任务(无/有返回值)**等;
@FunctionalInterface
public interface Runnable {
void run();
}
// 示例
Runnable task = () -> System.out.println("Running something...");
五、条件判断、过滤型
此类是Predicate系列接口,包含Predicate<T>
/ BiPredicate<T,U>
等;
适用于:列表过滤、断言判断、校验条件。
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
// 示例
Predicate<String> p = s -> s.isEmpty();
六、基础类型支持
为了避免装箱拆箱的性能损耗,JDK 还提供了很多 基础类型专用版本,如:
- IntSupplier
- DoubleConsumer
- LongPredicate
- ToIntFunction
- IntFunction
总结
**函数式接口(Functional Interface)**是 Java 8 引入的重要特性,以下是合理利用函数式接口将带来的价值和意义:
- 简化代码结构:函数式接口允许将行为作为参数传递,减少样板代码,提升开发效率。
- 增强代码可读性与复用性:结合 Lambda 表达式,代码更清晰,逻辑更集中,易于维护与扩展。
- 解耦业务逻辑:可替代传统的策略模式,使逻辑更具灵活性。
- 支持流式编程:与 Stream、Optional、CompletableFuture 等 Java 8+ API 深度集成,是函数式编程风格的基础。
- 有利于并发与测试:函数式接口多为无状态、不可变实现,天然支持并发编程和单元测试。
综上,合理利用函数式接口是现代 Java 编程中构建高质量、可维护系统的重要手段。