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 是 数据处理工具,不是容器
  • 核心思想是 流水线 + 函数式编程
  • 牢记三步:创建 → 中间操作 → 终止操作
  • 合理使用,不要滥用并行流
相关推荐
铁蛋AI编程实战10 分钟前
通义千问 3.5 Turbo GGUF 量化版本地部署教程:4G 显存即可运行,数据永不泄露
java·人工智能·python
晚霞的不甘21 分钟前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
SunnyDays101123 分钟前
使用 Java 冻结 Excel 行和列:完整指南
java·冻结excel行和列
摇滚侠34 分钟前
在 SpringBoot 项目中,开发工具使用 IDEA,.idea 目录下的文件需要提交吗
java·spring boot·intellij-idea
云姜.39 分钟前
java多态
java·开发语言·c++
李堇42 分钟前
android滚动列表VerticalRollingTextView
android·java
泉-java1 小时前
第56条:为所有导出的API元素编写文档注释 《Effective Java》
java·开发语言
zfoo-framework1 小时前
帧同步和状态同步
java
charlotte102410242 小时前
高并发:关于在等待学校教务系统选课时的碎碎念
java·运维·网络
亓才孓2 小时前
[JDBC]PreparedStatement替代Statement
java·数据库