AI 摘要
AI
正在生成摘要...

文章的整体框架由ChatGPT5进行生成,作者根据框架进行内容编写。

前言

入职一个多月以来,在日常开发中我发现一个使用到的非常高频的工具或者说API吧,那就是:Java Stream 流

不论是处理集合数据、过滤业务对象、还是对查询结果进行统计汇总,Stream 几乎无处不在。
如果说 List 是数据的容器,那么 Stream 就是让数据“动”起来的流水线。

这篇文章将结合我这段时间的项目体会,从概念、常用操作、实战案例三个方面,带大家深入理解 Stream 流。

一、Stream 是什么?

Stream 是 Java 8 引入的新特性,用于对集合(如 List、Set、Map)进行函数式操作。
它的核心思想是:

用声明式的方式对数据进行处理,而不是写 for 循环。

传统写法:

JAVA
List<String> names = new ArrayList<>();
for (User user : userList) {
    if (user.getAge() > 18) {
        names.add(user.getName());
    }
}

Stream 写法:

JAVA
List<String> names = userList.stream()
    .filter(user -> user.getAge() > 18)
    .map(User::getName)
    .collect(Collectors.toList());

通过对比是不是一眼清爽多了?代码更加的简洁、更容易读懂,也更容易维护。

二、Stream 的常见操作

Stream 的操作主要分为三类:

类型 方法 说明
创建流 stream()of() 从集合或数组创建流
中间操作 filter()map()sorted()distinct()limit()skip()flatMap() 用于数据处理和转换
终止操作 collect()forEach()count()findFirst()allMatch()anyMatch()noneMatch() 产生结果或副作用

1. 创建流

JAVA
List<String> list = Arrays.asList(\"Java\", \"Python\", \"C++\");
Stream<String> stream = list.stream(); // 从集合创建流
Stream<Integer> intStream = Stream.of(1, 2, 3, 4, 5); // 从数组创建流

2. 中间操作(返回新的 Stream)

TEXT
list.stream()
    .filter(s -> s.length() > 3)

3. 终止操作(生成结果)

TEXT
List<String> result = list.stream()
    .filter(s -> s.contains(\"a\"))
    .collect(Collectors.toList());

三、实战:在实际开发业务中使用 Stream

举个我在工作中遇到的例子:

需求:从数据库查出的设备列表中,筛选出租赁中(status = "using")的设备,按部门分组并统计数量。

假设我们有一个实体类:

JAVA
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Device {
    private String id;
    private String name;
    private String department;
    private String status;
}
JAVA
List<Device> devices = Arrays.asList(
    new Device(\"1\", \"挖掘机A\", \"土建部\", \"using\"),
    new Device(\"2\", \"吊车B\", \"机电部\", \"idle\"),
    new Device(\"3\", \"挖掘机C\", \"土建部\", \"using\"),
    new Device(\"4\", \"泵车D\", \"机电部\", \"using\")
);

需求 1:筛选出“使用中”的设备

JAVA
List<Device> usingDevices = devices.stream()
    .filter(d -> \"using\".equals(d.getStatus()))
    .collect(Collectors.toList());

需求 2:统计每个部门的设备数量

JAVA
Map<String, Long> countByDept = devices.stream()
    .collect(Collectors.groupingBy(Device::getDepartment, Collectors.counting()));

输出结果:

TEXT
{机电部=2, 土建部=2}

需求 3:获取设备名称列表并拼接成字符串

JAVA
String names = devices.stream()
    .map(Device::getName)
    .collect(Collectors.joining(\", \"));
System.out.println(names);
// 输出:挖掘机A, 吊车B, 挖掘机C, 泵车D

四、Stream 的一些高级用法

分组 + 过滤 + 映射 组合操作

JAVA
Map<String, List<String>> deptDeviceNames = devices.stream()
    .filter(d -> \"using\".equals(d.getStatus()))
    .collect(Collectors.groupingBy(
        Device::getDepartment,
        Collectors.mapping(Device::getName, Collectors.toList())
    ));

结果:

TEXT
{机电部=[泵车D], 土建部=[挖掘机A, 挖掘机C]}

求和与平均值

JAVA
List<Integer> nums = Arrays.asList(10, 20, 30, 40);
int sum = nums.stream().mapToInt(Integer::intValue).sum();
double avg = nums.stream().mapToInt(Integer::intValue).average().orElse(0);

五、总结

Stream 并不是为了“耍酷”,"看起来高级",而是让我们:

  • 高效 地操作集合数据
  • 优雅 地表达业务逻辑
  • 专注 于 “做什么”,而不是 “怎么做”

入职这段时间,我深刻体会到stream流的熟练使用会使开发效率大大提高。如果你还没在项目中使用过 Stream,建议从小模块开始尝试,相信你很快就会离不开它。

后记

后续我会继续补充一些关于stream流的高级用法,如:

  • Collectors 高级用法(分区、嵌套分组)
  • ParallelStream 并行流的性能与坑
  • 以及在 Spring Cloud项目中实际使用 Stream 的最佳实践

非常感谢你能读到这里,欢迎关注、收藏,一起进步!

评论