Java 8 引入的Stream API-stream()

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
    • [一、为什么要使用 Stream](#一、为什么要使用 Stream)
      • [对比:传统 for 循环 vs Stream](#对比:传统 for 循环 vs Stream)
    • [二、Stream 工作原理](#二、Stream 工作原理)
    • [三、Stream 操作分类](#三、Stream 操作分类)
      • [1. 中间操作(返回 Stream)](#1. 中间操作(返回 Stream))
      • [2. 终端操作(返回最终结果)](#2. 终端操作(返回最终结果))
    • [四、Stream vs 传统 for 循环性能](#四、Stream vs 传统 for 循环性能)
    • 五、总结

前言

stream() 是 Java 8 引入的 Stream API ,用于对集合进行声明式、函数式的数据处理。下面详细解释其原理和使用优势:


一、为什么要使用 Stream

对比:传统 for 循环 vs Stream

传统方式:

java 复制代码
for (ErpUseDepartment dept : departments) {
    if (dept == null) continue;
    if (StrUtil.equals(
        StringUtils.trim(document.getDeptCode()), 
        StringUtils.trim(dept.getDepartmentId())
    )) {
        return dept;
    }
}
return null;

Stream 方式:

java 复制代码
return departments.stream()
    .filter(Objects::nonNull)
    .filter(item -> StrUtil.equals(
        StringUtils.trim(document.getDeptCode()), 
        StringUtils.trim(item.getDepartmentId())
    ))
    .findFirst()
    .orElse(null);

优势对比:

维度 传统 for 循环 Stream API
代码可读性 冗长,需手动管理循环 简洁,声明式表达意图
并行处理 需手动实现 只需 parallelStream()
函数式组合 困难 支持链式调用
代码量 多 少

二、Stream 工作原理

核心概念

js 复制代码
数据源 → 中间操作 → 终端操作
    │          │          │
    ▼          ▼          ▼
 List      filter()    findFirst()
           map()       collect()
           sorted()    count()

执行流程

步骤1:创建 Stream

java 复制代码
departments.stream()  // 将 List 转换为 Stream

步骤2:中间操作(惰性求值)

java 复制代码
.filter(Objects::nonNull)  // 过滤 null,不立即执行
.filter(item -> ...)       // 过滤匹配条件,不立即执行

关键特点 :中间操作是惰性的,不会立即执行,只是构建操作流水线。

步骤3:终端操作(触发执行)

java 复制代码
.findFirst()  // 触发整个流水线执行
.orElse(null) // 处理 Optional 结果

关键特点 :只有遇到终端操作时,才会一次性执行整个流水线。

内部执行机制

java 复制代码
departments.stream()
    .filter(Objects::nonNull)           // 操作1
    .filter(item -> ...)                // 操作2
    .findFirst()                        // 终端操作
    .orElse(null);

实际执行过程:

元素 操作1 操作2 结果
dept1 通过 不匹配 继续
dept2 通过 不匹配 继续
dept3 通过 匹配 立即返回 dept3
dept4 未执行 未执行 -

短路特性:一旦找到匹配元素,立即终止遍历,不会处理剩余元素。


三、Stream 操作分类

1. 中间操作(返回 Stream)

操作 说明
filter(Predicate) 过滤元素
map(Function) 转换元素
sorted(Comparator) 排序
distinct() 去重
limit(long) 限制数量

2. 终端操作(返回最终结果)

操作 说明
findFirst() 返回第一个元素(Optional)
findAny() 返回任意元素(Optional)
collect(Collector) 收集为集合
count() 计数
forEach(Consumer) 遍历消费

四、Stream vs 传统 for 循环性能

性能对比

场景 性能 说明
小规模数据 几乎相同 Stream 有轻微开销
大规模数据 Stream 可能更快 可并行化
多核环境 Stream 优势明显 parallelStream() 自动并行

并行 Stream

只需将 stream() 改为 parallelStream():

java 复制代码
return departments.parallelStream()  // 并行处理
    .filter(Objects::nonNull)
    .filter(item -> ...)
    .findFirst()
    .orElse(null);

五、总结

为什么使用 Stream?

  1. 代码更简洁:用声明式代码表达"做什么",而非"怎么做"
  2. 可读性更强:链式调用清晰表达数据处理流程
  3. 易于并行化:一键开启并行处理
  4. 函数式编程:支持 Lambda 表达式,符合现代编程风格

工作原理:

  • 惰性求值:中间操作不立即执行
  • 短路优化:终端操作时按需处理,找到结果立即停止
  • 流水线执行:元素逐个经过所有操作,而非先执行完一个操作再执行下一个
相关推荐
东莞市云毅网络有限公司1 小时前
AI 引用句逐条回指原文:让回答可回溯的校验实现
python·数据清洗·rag·企业知识库·文档解析
Vex2une3 小时前
Windows 性能监视器发展史:从 PerfMon 计数器到 XPerf 深度诊断
windows·wpa·etw·性能监视器·perfmon·性能计数器·xperf
在角落发呆3 小时前
工具配置备份步骤:从手动备份到自动化方案
运维·windows·自动化
Sarvartha3 小时前
final 关键字
java·开发语言
2601_952047793 小时前
单一策略深度教程:用轻易云把集成任务的报错实时推送到钉钉机器人
java·机器人·钉钉
数字融合3 小时前
透明化视频三维矿山井下照明重建技术
人工智能·python·数码相机
yi0113 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
数据狐(Datafox)3 小时前
淘宝图片搜索 API 落地实战:基于以图搜货搭建跨境电商选品系统
java·大数据·微服务
Vd7H20A74 小时前
Windows 下用 llama.cpp 运行 Qwen3.8-27B 并开启 512K 上下文 完全指南
windows·llama