Java Stream 流(Stream API)详细讲解

Java Stream 流(Stream API)详细讲解

一、什么是 Stream 流

1.1 Stream 的本质

StreamJava 8 引入的一套用于 集合数据处理的函数式 API

需要明确几点:

  • Stream 不是数据结构
  • Stream 不存储数据
  • Stream 不修改原集合
  • Stream 关注的是 对数据的"计算过程"

可以把 Stream 理解为:

对集合中的数据,建立一条"流水线",数据依次经过各种操作,最终得到结果。


1.2 为什么要使用 Stream

在没有 Stream 之前,我们通常这样写代码:

java 复制代码
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = new ArrayList<>();

for (int x : list) {
    if (x % 2 == 0) {
        result.add(x * x);
    }
}

问题:

  • 代码冗长
  • 不利于并行计算

使用 Stream:

java 复制代码
List<Integer> result = list.stream()
        .filter(x -> x % 2 == 0)
        .map(x -> x * x)
        .toList();

二、Stream 的核心特点

2.1 三大特性

  1. 不存储数据
  2. 惰性执行
  3. 一次性消费

2.2 惰性执行示例

java 复制代码
list.stream()
    .filter(x -> {
        System.out.println("filter: " + x);
        return x > 2;
    });

上面代码 不会输出任何内容,因为:

没有终止操作,Stream 不会真正执行


三、Stream 的整体使用流程

Stream 使用分为 三步

复制代码
数据源 → 中间操作 → 终止操作

示意:

java 复制代码
list.stream()        // 获取流
    .filter(...)     // 中间操作
    .map(...)        // 中间操作
    .forEach(...);   // 终止操作

四、创建 Stream 的方式

4.1 从集合创建

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

4.2 从数组创建

java 复制代码
int[] arr = {1, 2, 3};
IntStream stream = Arrays.stream(arr);

4.3 使用 Stream.of

java 复制代码
Stream<String> stream = Stream.of("A", "B", "C");

4.4 创建无限流

java 复制代码
Stream<Integer> stream = Stream.iterate(0, x -> x + 2);
stream.limit(5).forEach(System.out::println);

五、中间操作(Intermediate Operations)

中间操作特点:

  • 返回新的 Stream
  • 支持链式调用
  • 不会立刻执行

5.1 filter(过滤)

java 复制代码
list.stream()
    .filter(x -> x > 3)
    .forEach(System.out::println);

5.2 map(映射)

java 复制代码
list.stream()
    .map(x -> x * 2)
    .forEach(System.out::println);

5.3 flatMap(扁平化)

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

lists.stream()
     .flatMap(List::stream)
     .forEach(System.out::println);

5.4 distinct(去重)

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

5.5 sorted(排序)

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

六、终止操作(Terminal Operations)

终止操作特点:

  • 触发 Stream 执行
  • 返回结果或副作用
  • 一个 Stream 只能有一个终止操作

6.1 forEach

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

6.2 collect

java 复制代码
List<Integer> newList = list.stream()
        .filter(x -> x > 2)
        .collect(Collectors.toList());

6.3 reduce(归约)

java 复制代码
int sum = list.stream()
        .reduce(0, Integer::sum);

6.4 count / anyMatch / allMatch

java 复制代码
long count = list.stream().count();
boolean hasEven = list.stream().anyMatch(x -> x % 2 == 0);

七、并行流(Parallel Stream)

7.1 使用方式

java 复制代码
list.parallelStream()
    .map(x -> x * x)
    .forEach(System.out::println);

或:

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

7.2 注意事项

  • 并行流 不保证顺序
  • 不适合 I/O 密集型任务
  • 共享变量可能产生线程安全问题

八、Stream 常见误区

8.1 Stream 会修改原集合?

不会。


8.2 Stream 可以重复使用?

不可以。

java 复制代码
Stream<Integer> s = list.stream();
s.forEach(System.out::println);
s.forEach(System.out::println); // 抛异常

九、Stream 与传统 for 循环对比

对比项 for 循环 Stream
编程风格 命令式 声明式
可读性 一般
并行能力 手动 内置
易错性

十、总结

  • Stream 是 数据处理工具,不是容器
  • 核心思想是 流水线 + 函数式编程
  • 牢记三步:创建 → 中间操作 → 终止操作
  • 合理使用,不要滥用并行流
相关推荐
像我这样帅的人丶你还11 小时前
Java 后端详解(四):分页与搜索
java·javascript·后端
她的男孩11 小时前
数据权限为什么不能只靠注解?Forge 的 Mapper 层 SQL 改写源码拆解
java·后端·架构
tntxia12 小时前
Mybatis的日志输入
java
亦暖筑序13 小时前
Java 8老系统Browser Agent实战:三层拦截把AI操作后台变成可审计流程
java·后端·设计模式
用户2986985301416 小时前
Java 实现 Word 文档加密与权限解除
java·后端
Yeats_Liao17 小时前
14:Servlet中的页面跳转-Java Web
java·后端·架构
未秃头的程序猿17 小时前
告别"if-else地狱"!Java 21模式匹配,代码优雅了10倍
java·后端·面试
鹤望兰67517 小时前
字节跳动国际支付-后端开发-三面面经
java
Flittly17 小时前
【AgentScope Java新手村系列】(14)人机交互
java·spring boot·spring
RainCity18 小时前
Java Swing 自定义组件库分享(十二)
java·笔记·后端