Stream API¶
如果你熟悉 JS 的 [1,2,3].filter(...).map(...),Java 的 Stream 你会直接上手——这是后端开发里前端人优势最明显的部分。
三步走¶
集合.stream() // 1. 创建流
.filter(...) // 2. 中间操作(可串多个,惰性:不触发执行)
.map(...) // 中间操作
.collect(...) // 3. 终止操作(触发真正执行,产出结果)
与 JS 数组方法对照¶
| JS | Java Stream | 说明 |
|---|---|---|
.filter(x => x>3) |
.filter(x -> x>3) |
过滤 |
.map(x => x*2) |
.map(x -> x*2) |
映射 |
.reduce((a,b)=>a+b, 0) |
.reduce(0, (a,b)->a+b) |
归约 |
.length |
.count() |
计数(终止操作) |
.forEach(x=>...) |
.forEach(x -> ...) |
遍历 |
完整链式示例¶
List<Integer> result = nums.stream()
.filter(n -> n % 2 == 0) // 偶数
.map(n -> n * 10) // ×10
.collect(Collectors.toList()); // 收集成 List
// [20, 40, 60]
关键差异¶
Stream 不是数组
- JS 的
.filter()直接返回新数组。Java 的 Stream 中间操作是惰性的,必须有个终止操作(collect/count/forEach)才会真正执行。 - 收集成 List 要
.collect(Collectors.toList()),不能直接当 List 用。 - Stream 只能消费一次(流过即逝),不像数组能反复遍历。
Optional:优雅处理"可能没有"¶
Integer first = nums.stream()
.filter(n -> n > 10)
.findFirst() // 返回 Optional<Integer>
.orElse(null); // 找不到时兜底(对标 JS 的 ?? / ||)
Optional 是 Java 用来避免 NullPointerException 的容器——"可能有值也可能没有"。第三篇业务代码会常用。
实战¶
Stream 在后端处理集合数据时极其常用:把 List<Entity> 转成 List<VO>、过滤、分组、统计。MyBatis-Plus 查出来的数据经常配合 Stream 加工后返回前端。
完整可运行示例¶
package com.javaglm.language.ch16;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 第 16 章 · Stream API。
* Stream 对标 JS 数组的链式调用:.filter().map().reduce()。
* 这是前端人最舒适的 API,几乎一一对应。
* 三步:创建 stream → 中间操作(filter/map,惰性)→ 终止操作(collect/count,触发执行)。
*/
public class StreamDemo {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6);
// 1. filter:对标 .filter(x => x > 3)
List<Integer> big = nums.stream()
.filter(n -> n > 3)
.collect(Collectors.toList()); // collect = 收集成 List
System.out.println("大于3的 = " + big); // [4, 5, 6]
// 2. map:对标 .map(x => x * x)
List<Integer> squares = nums.stream()
.map(n -> n * n)
.collect(Collectors.toList());
System.out.println("平方 = " + squares); // [1, 4, 9, 16, 25, 36]
// 3. 链式组合:偶数 → ×10 → 收集
List<Integer> chain = nums.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 10)
.collect(Collectors.toList());
System.out.println("偶数×10 = " + chain); // [20, 40, 60]
// 4. 求和:reduce / 简便 sum
int sum = nums.stream().mapToInt(n -> n).sum();
System.out.println("总和 = " + sum); // 21
// 5. count:统计个数
long count = nums.stream().filter(n -> n > 3).count();
System.out.println("大于3的个数 = " + count); // 3
// 6. findFirst + Optional:处理"可能找不到"
Integer firstBig = nums.stream()
.filter(n -> n > 10)
.findFirst() // 返回 Optional<Integer>
.orElse(null); // 没有就返回 null(对标 ?? 兜底)
System.out.println("第一个>10的 = " + firstBig); // null
}
}
:octicons-arrow-left-16: 上一章:Lambda | 下一章:IO 与文件基础