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 是 数据处理工具,不是容器
  • 核心思想是 流水线 + 函数式编程
  • 牢记三步:创建 → 中间操作 → 终止操作
  • 合理使用,不要滥用并行流
相关推荐
日月云棠13 小时前
各版本JDK对比:JDK 25 特性详解
java
用户83071968408214 小时前
Spring Boot 项目中日期处理的最佳实践
java·spring boot
JavaGuide14 小时前
Claude Opus 4.6 真的用不起了!我换成了国产 M2.5,实测真香!!
java·spring·ai·claude code
IT探险家14 小时前
Java 基本数据类型:8 种原始类型 + 数组 + 6 个新手必踩的坑
java
花花无缺14 小时前
搞懂new 关键字(构造函数)和 .builder() 模式(建造者模式)创建对象
java
用户9083246027315 小时前
Spring Boot + MyBatis-Plus 多租户实战:从数据隔离到权限控制的完整方案
java·后端
桦说编程15 小时前
实战分析 ConcurrentHashMap.computeIfAbsent 的锁冲突问题
java·后端·性能优化
程序员清风19 小时前
用了三年AI,我总结出高效使用AI的3个习惯!
java·后端·面试
beata20 小时前
Java基础-13: Java反射机制详解:原理、使用与实战示例
java·后端
用户03321266636720 小时前
Java 使用 Spire.Presentation 在 PowerPoint 中添加或删除表格行与列
java