Java 8 Stream 流操作大全:从入门到实战全覆盖(附案例)

引言

Java 8 中的 Stream 是处理集合的终极利器,它提供了声明式、函数式的操作方式。本文将全面梳理 Stream 的核心操作及实际案例,适合所有 Java 开发者学习收藏!


🔍 一、什么是 Stream?

Stream 是 Java 8 引入的一个重要新特性,它不是数据结构,而是对集合(Collection)、数组等数据源进行链式、高效处理的一种方式。

特点:

  • 声明式编程(更少的代码、更高的可读性)
  • 支持并行(parallel)
  • 不改变原数据源(函数式思想)
  • 延迟执行(惰性求值)

🧱 二、Stream 的核心组成

类型 说明
数据源 如 List、Set、数组、Map 的 entrySet 等
中间操作 多次链式调用,返回 Stream 自身
终结操作 最终计算结果,触发 Stream 执行链关闭

✨ 三、Stream 创建方式

✅ 从集合创建

java 复制代码
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();

✅ 从数组创建

java 复制代码
String[] arr = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(arr);

✅ 通过 Stream.of()

java 复制代码
Stream<Integer> stream = Stream.of(1, 2, 3, 4);

✅ 无限流(函数式)

java 复制代码
Stream<Integer> infinite = Stream.iterate(0, x -> x + 2).limit(5);
infinite.forEach(System.out::println); // 输出0 2 4 6 8

🧪 四、Stream 中间操作详解(中间操作不会立刻执行)

1️⃣ filter:过滤元素

java 复制代码
List<String> list = Arrays.asList("apple", "banana", "cherry");
list.stream().filter(s -> s.startsWith("a")).forEach(System.out::println);

2️⃣ map:元素映射

java 复制代码
List<String> upper = list.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());

3️⃣ flatMap:扁平化嵌套结构

java 复制代码
List<String> lines = Arrays.asList("a,b", "c,d", "e");
List<String> result = lines.stream()
    .flatMap(s -> Arrays.stream(s.split(",")))
    .collect(Collectors.toList());

4️⃣ distinct:去重

java 复制代码
Stream.of(1, 2, 2, 3, 3).distinct().forEach(System.out::println);

5️⃣ sorted:排序

java 复制代码
list.stream().sorted().forEach(System.out::println); // 默认自然排序

自定义排序:

java 复制代码
list.stream()
    .sorted((s1, s2) -> s2.length() - s1.length())
    .forEach(System.out::println);

6️⃣ limit / skip:限制/跳过元素

java 复制代码
Stream.iterate(1, n -> n + 1)
    .skip(3)
    .limit(5)
    .forEach(System.out::println); // 输出4,5,6,7,8

7️⃣ peek:调试用的中间操作

java 复制代码
List<String> result = list.stream()
    .peek(System.out::println)
    .map(String::toUpperCase)
    .collect(Collectors.toList());

🎯 五、Stream 终结操作详解(触发流执行)

1️⃣ forEach:遍历处理每个元素

java 复制代码
list.stream().forEach(System.out::println);

2️⃣ collect:结果收集(常用于转为 List、Map)

java 复制代码
List<String> upper = list.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());

收集为 Map:

java 复制代码
Map<String, Integer> map = list.stream()
    .collect(Collectors.toMap(s -> s, String::length));

3️⃣ toSet / joining / groupingBy / partitioningBy

java 复制代码
Set<String> set = list.stream().collect(Collectors.toSet());

String joined = list.stream().collect(Collectors.joining(", "));

Map<Integer, List<String>> grouped = list.stream()
    .collect(Collectors.groupingBy(String::length));

Map<Boolean, List<String>> partitioned = list.stream()
    .collect(Collectors.partitioningBy(s -> s.contains("a")));

4️⃣ reduce:归约操作(聚合)

java 复制代码
int sum = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);

5️⃣ count / min / max

java 复制代码
long count = list.stream().count();

Optional<String> max = list.stream().max(Comparator.comparing(String::length));

6️⃣ anyMatch / allMatch / noneMatch

java 复制代码
boolean any = list.stream().anyMatch(s -> s.contains("a"));
boolean all = list.stream().allMatch(s -> s.length() > 2);
boolean none = list.stream().noneMatch(s -> s.startsWith("z"));

7️⃣ findFirst / findAny

java 复制代码
Optional<String> first = list.stream().findFirst();
Optional<String> any = list.parallelStream().findAny();

🔄 六、实战案例综合

✅ 案例:按姓名分组统计员工人数

java 复制代码
Map<String, Long> result = employees.stream()
    .collect(Collectors.groupingBy(Employee::getName, Collectors.counting()));

✅ 案例:分区 -> 年龄是否大于 30

java 复制代码
Map<Boolean, List<Employee>> partition = employees.stream()
    .collect(Collectors.partitioningBy(e -> e.getAge() > 30));

✅ 案例:多条件排序(先按部门,再按年龄)

java 复制代码
employees.stream()
    .sorted(Comparator.comparing(Employee::getDepartment)
        .thenComparing(Employee::getAge))
    .collect(Collectors.toList());

🚨 七、使用建议 & 注意事项

  • Stream 是一次性操作,操作后不能再次使用
  • 要避免流操作嵌套过深,影响可读性
  • 注意延迟执行行为,中间操作不触发执行
  • 尽量避免使用 collect().get() 导致空指针异常

📚 八、总结:流操作速查表

操作类型 方法 说明
创建 stream(), of(), iterate() 创建流
中间操作 filter, map, flatMap, distinct, sorted, limit, skip, peek 构建处理链
终结操作 forEach, collect, reduce, count, anyMatch, findFirst, toMap 执行处理,返回结果

🔚 九、推荐扩展阅读

📌 点赞 + 收藏 + 关注,每天带你掌握底层原理,写出更强健的 Java 代码!