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 是 数据处理工具,不是容器
  • 核心思想是 流水线 + 函数式编程
  • 牢记三步:创建 → 中间操作 → 终止操作
  • 合理使用,不要滥用并行流
相关推荐
寻星探路2 小时前
【全景指南】JavaEE 深度解析:从 Jakarta EE 演进、B/S 架构到 SSM 框架群实战
java·开发语言·人工智能·spring boot·ai·架构·java-ee
七夜zippoe2 小时前
微服务架构演进实战 从单体到微服务的拆分原则与DDD入门
java·spring cloud·微服务·架构·ddd·绞杀者策略
洛_尘2 小时前
JAVA EE初阶8:网络原理 - HTTP_HTTPS(重要)
java·http·java-ee
独断万古他化2 小时前
【Java 网络编程全解】Socket 套接字与 TCP/UDP 通信实战全解
java·网络编程·socket
牧小七2 小时前
java14的新特性
java
努力努力再努力wz3 小时前
【Linux网络系列】:JSON+HTTP,用C++手搓一个web计算器服务器!
java·linux·运维·服务器·c语言·数据结构·c++
魂梦翩跹如雨3 小时前
死磕排序算法:手撕快速排序的四种姿势(Hoare、挖坑、前后指针 + 非递归)
java·数据结构·算法
带刺的坐椅10 小时前
Solon AI Skills 会是 Agent 的未来吗?
java·agent·langchain4j·solon-ai
jacGJ10 小时前
记录学习--文件读写
java·前端·学习