当前位置: 首页 > news >正文

Java中使用Stream API优化for循环

业务逻辑:计算总额

原来使用for的逻辑代码

// 计算总额
double total = 0.0;
for (RkDetail rkDetail: rkDetailList) {if (rkDetail.getTotal() != null) {total += rkDetail.getTotal();}
}

使用Java 8 Stream API实现,使代码更简洁且易读 

// 计算总额
double total = rkDetailList.stream().filter(r -> r.getTotal() != null).mapToDouble(RkDetail::getTotal).sum();

让我们一步步拆解这段代码的含义,用生活中快递分拣的场景帮助你理解:

double total = rkDetailList.stream()      // 【开启传送带】.filter(r -> r.getTotal() != null)    // 【安检仪-过滤空包裹】.mapToDouble(RkDetail::getTotal)      // 【拆包取物】.sum();                               // 【自动累加】

1. 开启传送带 rkDetailList.stream()

想象你有一个装满快递包裹的货架(rkDetailList),现在要启动一条传送带处理这些包裹。
stream() 就像启动传送带,让包裹(列表中的每个 RkDetail 对象)依次进入处理流程。

📦📦📦📦 包裹们排着队进入传送带...


2. 安检仪过滤 filter(r -> r.getTotal() != null)

传送带上的第一个设备是安检仪,它会检查每个包裹:
r -> r.getTotal() != null 表示 "只允许装有金额的包裹通过"
(这里的 r 代表每个快递包裹,getTotal() 查看包裹内的金额单)

✅ 有金额单的包裹通过
❌ 空包裹(金额单为null)被丢弃

📦✅ -> 金额100元
📦❌ -> 金额单丢失
📦✅ -> 金额50元
📦✅ -> 金额200元


3. 拆包取物 mapToDouble(RkDetail::getTotal)

通过安检的包裹来到拆包工位,这里的工作人员会:
RkDetail::getTotal 表示 "拆开包裹,只取出里面的金额单"
mapToDouble 将金额单上的数字转换为计算机能直接计算的数值(double类型)

输入:📦✅ -> 输出:100.0
输入:📦✅ -> 输出:50.0
输入:📦✅ -> 输出:200.0


4. 自动累加 sum()

最后来到自动累加器,它会将所有金额单上的数值相加:
sum() 自动完成 100.0 + 50.0 + 200.0 = 350.0

💰 最终总额:350.0


完整流程示意图

原始包裹队列 → [传送带] → [安检过滤] → [拆包取数] → [自动求和](List)      (stream())   (filter)     (mapToDouble)   (sum)

重点记忆口诀

  1. 流式处理三步走:取流 → 过滤 → 转换

  2. 箭头符号看数据-> 左边是输入,右边是处理逻辑

  3. 双冒号是快捷方式类名::方法名 等价于 x -> x.方法名()

实际案例演示

假设原始数据:

RkDetail 包裹1 = new RkDetail(100.0);
RkDetail 包裹2 = new RkDetail(null);    // 空包裹
RkDetail 包裹3 = new RkDetail(50.0);
List<RkDetail> rkDetailList = Arrays.asList(包裹1, 包裹2, 包裹3);

代码执行过程:

  1. 包裹2 在 filter 阶段被过滤

  2. 包裹1 和 包裹3 的金额被提取

  3. 计算 100.0 + 50.0 = 150.0

最终 total 的值为 150.0

通过这种生活化的类比,是不是更容易理解Stream流的工作原理了呢?在实际开发中,这种处理方式比传统for循环更直观,尤其适合处理复杂的数据流水线操作。

 

优化点说明:

  1. Stream API 替代显式循环

    • 通过流式操作 stream() + filter() + mapToDouble() + sum() 链式调用,消除手动循环和中间变量,代码更简洁

    • 逻辑表达更声明式(描述做什么,而非如何做)

  2. 空值过滤更直观

    • filter(r -> r.getTotal() != null) 直接体现空值过滤逻辑,一目了然

  3. 避免中间状态变量

    • 原始代码需要维护 total 变量和循环体,流式操作直接通过无状态计算得到结果

扩展优化建议(视场景选用):

  1. 并行流加速

    java

    复制

    下载

    // 仅当列表极大且线程安全时使用
    double total = rkDetailList.parallelStream().filter(r -> r.getTotal() != null).mapToDouble(RkDetail::getTotal).sum();
  2. 空集合防御

    java

    复制

    下载

    // 如果 rkDetailList 可能为 null(根据业务场景决定是否添加)
    List<RkDetail> safeList = Optional.ofNullable(rkDetailList).orElse(Collections.emptyList());
    double total = safeList.stream()... // 后续操作同上
  3. 方法引用(若允许空值)

    java

    复制

    下载

    // 如果 RkDetail::getTotal 不可能返回 null(注意与当前场景冲突)
    double total = rkDetailList.stream().mapToDouble(RkDetail::getTotal).sum();

最终选择建议:
若运行环境是Java 8+且列表规模可控,推荐使用基础优化版本,兼顾简洁性与可维护性。

相关文章:

  • ELF格式·链接与加载
  • 网络协议与通信安全
  • Spring MVC深度解析:控制器与视图解析及RESTful API设计最佳实践
  • Linux常用下载资源命令
  • 互联网大厂Java求职面试实录 —— 严肃面试官遇到搞笑水货程序员
  • 动态IP:像变色龙一样自由切换网络身份
  • 深度学习实战:从图像分类到文本生成的完整案例解析
  • python项目和依赖管理工具uv简介
  • 行为型:迭代器模式
  • 为什么Python慢?如何用Numba实现Python百倍加速?
  • CSS入门
  • java基础(继承)
  • C/C++---隐式显式转换
  • Disruptor—2.并发编程相关简介
  • MQTT-排它订阅
  • SQL注入基础
  • Kotlin全栈工程师转型路径
  • 矩阵方程$Ax=b$的初步理解.
  • 开发者工具箱-鸿蒙大小写转换开发笔记
  • PHP后端
  • 网站个别页面做seo/十大场景营销案例
  • wordpress弹出搜索结果/手机seo百度点击软件
  • 女生做网站编辑好吗/网站是否含有seo收录功能
  • 做美食直播哪个网站好/网站优化员seo招聘
  • 门户网站建设注意事项/湖南企业seo优化报价
  • 哪个网站可以做计算机二级的题/正规网络公司关键词排名优化