Java内置函数式接口与Stream API天然搭配:Predicate用于filter筛选、Function用于map转换、Consumer用于forEach消费、Supplier用于generate生成,各接口严格对应操作语义,支撑声明式链式处理。

Java 内置函数式接口和 Stream API 是一对天然搭档,它们共同支撑起声明式、链式的数据处理风格。核心在于:每个 Stream 的中间操作(如 filter、map)都明确要求某种函数式接口作为参数,而 Lambda 表达式或方法引用正是实现这些接口最简洁的方式。
Predicate 用于过滤(filter)
Predicate<t></t> 接收一个 T 类型参数,返回 boolean,正好匹配 filter 的语义——“要不要留下这个元素?”
- 常见写法:
stream.filter(x -> x > 10)或stream.filter(Objects::nonNull) - 可复用逻辑:定义
Predicate<String> startsWithA = s -> s != null && s.startsWith("A");,然后list.stream().filter(startsWithA).collect(...) - 注意:
filter不改变元素本身,只决定是否传递给后续环节
Function 用于转换(map)
Function<t r></t> 接收 T,返回 R,对应 map 的“把每个元素变成另一种形式”的需求。
- 典型用例:
stream.map(String::toUpperCase)、stream.map(person -> person.getName()) - 支持链式转换:比如
map(s -> s.trim()).map(String::length),先去空格再算长度 - 返回类型可以不同,所以
Stream<String>经map(Integer::parseInt)后变成Stream<Integer>
Consumer 用于消费(forEach / peek)
Consumer<t></t> 接收 T,不返回值(void),适合执行副作用操作,比如打印、存库、发消息。
立即学习“Java免费学习笔记(深入)”;
-
forEach是终端操作,执行后流就关闭了:stream.forEach(System.out::println) -
peek是中间操作,常用于调试:stream.peek(System.out::println).filter(...) - 避免在
forEach中修改外部变量(尤其并行流),推荐用collect等纯函数式方式聚合结果
Supplier 用于生成流(generate / iterate)
Supplier<t></t> 不需要输入,只提供 T 类型的值,是创建无限流或动态数据源的关键。
-
Stream.generate(() -> Math.random())每次调用都产生一个新随机数 -
Stream.iterate(0, n -> n + 1)本质也是 Supplier + UnaryOperator 的组合 - 配合
limit(n)截断,才能得到有限流:Stream.generate(UUID::randomUUID).limit(5)
真正用起来并不复杂,关键在于记住每个操作背后的接口契约:filter 要 boolean、map 要新对象、forEach 只要执行动作、generate 只管“给一个”。写熟了,看到方法签名就能条件反射出该用哪个接口。


















