Java Stream API(流式编程接口)是在 Java 8 引入的,用于对集合(Collection)或数组进行高效、简洁、并行的操作。
🚀 一、什么是 Stream(流)
Stream 不是集合,它是一种 对数据进行操作的"视图" 。可以理解为一条"数据流水线":
- 数据来源:集合、数组、文件、IO等;
- 中间操作:过滤、排序、映射、分组;
- 终止操作:收集、计数、求和、遍历。
示例:
plain
List<String> names = List.of("张三", "李四", "王五", "张三丰");
List<String> result = names.stream()
.filter(name -> name.startsWith("张")) // 过滤姓张
.distinct() // 去重
.sorted() // 排序
.collect(Collectors.toList()); // 收集为列表
System.out.println(result); // 输出: [张三, 张三丰]
🧱 二、Stream 的基本结构
1️⃣ 创建流
常见的几种方式:
plain
// 从集合创建
Stream<String> s1 = list.stream();
// 从数组创建
Stream<Integer> s2 = Arrays.stream(new Integer[]{1, 2, 3});
// 直接创建
Stream<String> s3 = Stream.of("A", "B", "C");
// 无限流(常用于测试或算法)
Stream<Integer> s4 = Stream.iterate(0, n -> n + 2).limit(5); // 0,2,4,6,8
2️⃣ 中间操作(Intermediate Operations)
这些操作会返回一个新的 Stream,不会立即执行,直到终止操作发生时才会触发。
| 方法 | 功能 | 示例 |
|---|---|---|
filter(Predicate) |
过滤 | .filter(x -> x > 5) |
map(Function) |
转换元素 | .map(x -> x * 2) |
flatMap(Function) |
扁平化嵌套流 | .flatMap(list -> list.stream()) |
distinct() |
去重 | .distinct() |
sorted() |
排序 | .sorted() 或 .sorted(Comparator) |
limit(n) |
取前 n 个 | .limit(5) |
skip(n) |
跳过前 n 个 | .skip(3) |
peek(Consumer) |
调试查看 | .peek(System.out::println) |
示例:
plain
List<Integer> nums = List.of(1, 2, 3, 4, 5, 6);
nums.stream()
.filter(n -> n % 2 == 0) // 过滤偶数
.map(n -> n * n) // 平方
.forEach(System.out::println); // 输出: 4, 16, 36
3️⃣ 终止操作(Terminal Operations)
这些方法会触发实际执行,返回结果或执行动作。
| 方法 | 功能 | 示例 |
|---|---|---|
forEach(Consumer) |
遍历 | .forEach(System.out::println) |
collect(Collector) |
收集结果 | .collect(Collectors.toList()) |
count() |
计数 | .count() |
findFirst() |
找第一个 | .findFirst().orElse(null) |
findAny() |
找任意一个(并行流) | .findAny() |
anyMatch(Predicate) |
存在匹配 | .anyMatch(x -> x > 10) |
allMatch(Predicate) |
全部匹配 | .allMatch(x -> x > 0) |
noneMatch(Predicate) |
全部不匹配 | .noneMatch(x -> x < 0) |
max(Comparator) |
最大值 | .max(Integer::compare) |
min(Comparator) |
最小值 | .min(Integer::compare) |
reduce() |
累加、归约 | .reduce(0, (a,b)->a+b) |
示例:
plain
int sum = List.of(1, 2, 3, 4, 5)
.stream()
.reduce(0, Integer::sum); // 求和
System.out.println(sum); // 15
🧩 三、收集器(Collectors)
Collectors 是 Stream 最强大的工具之一,用于把流的结果转成各种形式:
🔹 转换为集合
plain
.collect(Collectors.toList());
.collect(Collectors.toSet());
.collect(Collectors.toMap(User::getId, User::getName));
🔹 分组
plain
Map<String, List<User>> byDept = users.stream()
.collect(Collectors.groupingBy(User::getDeptName));
🔹 多级分组
plain
Map<String, Map<String, List<User>>> multiGroup = users.stream()
.collect(Collectors.groupingBy(User::getDeptName,
Collectors.groupingBy(User::getGender)));
🔹 聚合统计
plain
Double avg = users.stream()
.collect(Collectors.averagingInt(User::getAge)); // 平均年龄
🔹 拼接字符串
plain
String names = users.stream()
.map(User::getName)
.collect(Collectors.joining(", ", "[", "]"));
输出示例:
plain
[张三, 李四, 王五]
⚡ 四、flatMap 扁平化(常见难点)
flatMap() 把 嵌套集合 展开成一个扁平的流。
示例:
plain
List<List<String>> nested = List.of(
List.of("A", "B"),
List.of("C", "D")
);
List<String> flat = nested.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
System.out.println(flat); // [A, B, C, D]
🧠 五、并行流(Parallel Stream)
只需 .parallelStream(),即可让处理自动并行,提高性能(适合大数据量场景):
plain
long count = list.parallelStream()
.filter(x -> x > 100)
.count();
⚠️ 注意:
- 并行流开销较大,不适合小集合;
- 注意线程安全,尤其是写共享变量时。
🛠️ 六、自定义排序与过滤
plain
List<User> sorted = users.stream()
.filter(u -> u.getAge() > 18)
.sorted(Comparator.comparing(User::getAge).reversed())
.collect(Collectors.toList());
🧾 七、常见高级技巧
✅ 去重(按字段)
plain
List<User> unique = users.stream()
.filter(distinctByKey(User::getId))
.collect(Collectors.toList());
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
✅ 统计字段总和
plain
int totalAge = users.stream()
.mapToInt(User::getAge)
.sum();
✅ 分页(Stream 模拟分页)
plain
List<User> pageList = users.stream()
.skip((pageNum - 1) * pageSize)
.limit(pageSize)
.collect(Collectors.toList());
✅ 八、总结口诀
| 阶段 | 方法示例 | 说明 |
|---|---|---|
| 创建流 | stream() / of() |
创建流对象 |
| 中间操作 | filter()、map()、sorted() |
不会立即执行 |
| 终止操作 | collect()、count()、forEach() |
触发执行 |
| 收集器 | Collectors.toList() |
转换为集合 |
| 常用高级 | groupingBy()、joining() |
分组与聚合 |