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

Stream API 中的 forEach

        Java 8 引入的 Stream API 为数据集合提供了一种高效且声明式的处理方式。forEach 方法作为 Stream API 中的终端操作之一,其作用是对流中的每一个元素执行特定的操作。为了深入了解 forEach 的内部工作机制,我们需要探讨 Stream API 的实现细节,特别是 SpliteratorForkJoinPool 的角色。

Spliterator

   Spliterator(可拆分迭代器)是 Stream API 的核心组件,它不仅提供了遍历数据的能力,还支持数据源的分割,这使其非常适合并行处理。Spliterator 具有如下特性:

                  1. 遍历:按序遍历元素。

                  2. 分割:将数据源分割成多个部分,每部分可以被不同线程独立处理。

                  3. 特性描述:表达数据源的属性,比如是否排序、能否并行处理等。

                  4. 大小估算:估计尚未遍历的元素数量。

顺序流中的 forEach

        在顺序流中,forEach 通过调用 SpliteratortryAdvance 方法来遍历所有元素。此方法尝试对当前元素执行指定动作,若成功则返回 true,否则返回 false 表示无更多元素可处理。

并行流中的 forEach

        并行流中 forEach 的实现更为复杂,因为它需要使用多线程来并行处理数据。这里涉及到 ForkJoinPool 以及 Spliterator 的分割机制。

ForkJoinPool

   ForkJoinPool 是 Java 中一种特殊的线程池,专为能够分解为更小子任务的任务设计。它运用了工作窃取算法来均衡线程间的工作负荷。当某一线程完成自身任务后,可以从其他线程的任务队列中获取额外任务以执行,从而提升整体执行效率。

惰性求值

        Stream API 遵循惰性求值原则,即中间操作并不会立即执行,直到遇到终端操作(如 forEach)才触发整个管道的计算。这一机制让 Stream API 可以在最终执行前进行优化,如决定是否启用并行处理。

forEach 方法的并发修改问题

        在使用 forEach 方法遍历集合时尝试修改该集合,可能会引发 ConcurrentModificationException,尤其是在顺序流的情况下。对于并行流,虽然未必直接抛出异常,但这种做法依然可能导致不可预知的行为或并发问题。

       如何安全地修改集合

               为了避免此类问题,可以采取以下策略:

                    1. 使用 removeIf 方法:

list.removeIf(s -> "b".equals(s));

                    2. 通过迭代器安全地移除元素:

Iterator<String> it = list.iterator();
while (it.hasNext()) {if ("b".equals(it.next())) {it.remove();}
}

                    3. 创建过滤后的副本:

List<String> filteredList = list.stream().filter(s -> !"b".equals(s)).collect(Collectors.toList());

       综上所述,在顺序或并行流中直接修改正在被遍历的集合是不推荐的,应考虑使用上述推荐方法以保证程序的稳定性和安全性。


http://www.mrgr.cn/news/69022.html

相关文章:

  • lab2:docker基础实战
  • 【eNSP】路由基础与路由来源——静态路由实验
  • 如何修改npm包
  • layui的table组件中,对某一列的文字设置颜色为浅蓝怎么设置
  • HTML5:网页开发的新纪元
  • 人工智能学习框架:深入构建智能系统的基础
  • Linux内核USB2.0驱动框架分析--USB设备枚举过程
  • MybatisPlus入门(十)MybatisPlus-逻辑删除和多记录操作
  • 使用HTML、CSS和JavaScript创建动态雪人和雪花效果
  • JVM中对象在堆中的生命周期?
  • 会话技术-JWT令牌和filter
  • 如何快速关闭Linux上的服务脚本
  • 共享经济下的SpringBoot汽车管理创新
  • 电脑屏幕录像软件哪个好?这五款屏幕录像工具实打实推荐,记录精彩的瞬间!
  • 高效建造,全新体验:气膜网球馆的革新之选—轻空间
  • SpringBoot技术下的共享汽车运营平台
  • Result和ResultCode类,用于封装后端返回给前端的数据
  • 基于Python的自然语言处理系列(57):使用最佳表示向量法实现整本书的高效摘要
  • 06 P2437 蜜蜂路线
  • HTTP 和 HTTPS 的区别 - 2024最新版前端秋招面试短期突击面试题【100道】
  • 【操作系统】死锁
  • 【详解】斜率优化 DP + 凸包
  • kettle开发-Day43-数据对比
  • java day04-面向对象基础02
  • 基于java宠物医院管理系统的设计与实现
  • bat调用Perl脚本接收不到参数