一、 什么是 Stream 流?

简单来说,Stream(流)就是Java 8 提供的一套处理集合(List, Set, Map)的工具 API

不要把它和 IO 流(FileInputStream)混淆。IO 流是处理“文件传输”的,而 Stream 流是处理“内存数据计算”的。

它的核心思想是: 把集合看作一条流水线,元素在上面流动,我们可以经过一系列的工序(过滤、去重、映射、排序),最后包装成我们需要的结果。

为什么要用它?

  1. 代码简洁:告别层层嵌套的 if-elsefor 循环。
  2. 逻辑清晰:一看代码就知道在做什么(声明式编程)。
  3. 功能强大:一行代码搞定过滤、排序、分组、转换。

二、 Stream 流的“三板斧”

使用 Stream 流,永远只有三个步骤:

数据源 -> 中间操作 -> 终结操作

  1. 开启流 (Source):把集合变成流(如 list.stream())。
  2. 中间操作 (Intermediate):对流里的数据进行处理(过滤、转换、排序等)。注意:中间操作是“懒”的,不碰到终结操作绝不干活。
  3. 终结操作 (Terminal):把流里的数据收集起来,变成 List、Map 或者直接打印。

三、 实战:最常用的 4 个场景

场景 1:类型转换 / 对象映射 (Map) 最常用

需求:从数据库查出了一堆 User 实体对象,包含了密码等敏感信息。现在需要把它们转换成 UserDTO 传给前端。

以前的写法 (for 循环):

Java

List<UserDTO> dtoList = new ArrayList<>();
for (User user : userList) {
    UserDTO dto = new UserDTO();
    // 假设用了 Hutool
    BeanUtil.copyProperties(user, dto);
    dtoList.add(dto);
}

Stream 写法:

Java

List<UserDTO> dtoList = userList.stream() // 1. 开流
    .map(user -> BeanUtil.copyProperties(user, UserDTO.class)) // 2. 映射:把 User 变成 UserDTO
    .collect(Collectors.toList()); // 3. 收集

解析.map() 是最核心的方法,它的意思是“把流里的每一个元素,变成另一个东西”。


场景 2:数据过滤 (Filter)

需求:找出一堆博客中,点赞数大于 100 的那些博客。

Stream 写法:

Java

List<Blog> hotBlogs = records.stream()
    .filter(blog -> blog.getLiked() > 100) // 2. 过滤:返回 true 的留下,false 的扔掉
    .collect(Collectors.toList());

场景 3:类型强转与处理 (map + 方法引用)

需求:Redis 里取出的 ID 是 String 类型的(如 "101", "102"),需要转成 Long 类型去查数据库。

Stream 写法:

Java

List<String> idStrs = Arrays.asList("101", "102", "103");

List<Long> ids = idStrs.stream()
    .map(Long::valueOf) // 等同于 .map(s -> Long.valueOf(s))
    .collect(Collectors.toList());

场景 4:去重与排序 (Distinct & Sorted)

需求:有一堆无序且重复的数字,想给它们排序并去重。

Stream 写法:

Java

List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);

List<Integer> result = numbers.stream()
    .distinct() // 去重
    .sorted()   // 排序 (默认从小到大)
    .collect(Collectors.toList());

// 结果:[1, 2, 3, 4, 5, 6, 9]

四、 进阶:List 转 Map

这是开发中非常高频的场景。 需求:有一个 User 列表,我想变成一个 Map<Long, User>,key 是 userId,value 是 User 对象本身,方便后续通过 ID 快速查找。

Stream 写法:

Java

Map<Long, User> userMap = userList.stream()
    .collect(Collectors.toMap(User::getId, user -> user));

解析Collectors.toMap 接收两个参数,第一个指定谁做 Key,第二个指定谁做 Value。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐