java基础 流(Stream)

Stream

  • Stream 的核心概念
    • 核心特点
  • Stream 的操作分类
    • 中间操作(Intermediate Operations)
    • 终止操作(Terminal Operations)
  • Stream 的流分类
    • 顺序流(Sequential Stream)
    • 并行流(Parallel Stream)
      • 并行流的注意事项
      • 并行流的底层机制
    • 顺序流 vs 并行流的对比
    • 顺序流和并行流的示例代码
    • 顺序流并行流总结

Stream 的核心概念

Java 8 引入的 Stream API 是一种基于函数式编程的数据处理抽象,允许以声明式方式操作集合(如过滤、映射、排序等)。Stream 不是数据结构,而是对数据源(集合、数组、I/O 等)的高效计算工具

核心特点

  • 链式调用:通过多个操作(中间操作 + 终止操作)串联处理数据
  • 惰性求值:中间操作(如 filter, map)不会立即执行,直到遇到终止操作(如 collect, forEach)
  • 不可复用:一个 Stream 只能被消费一次,再次使用会抛出 IllegalStateException
  • 并行处理:可通过简单方法(parallel())实现多线程并行计算

Stream 的操作分类

中间操作(Intermediate Operations)

返回新的 Stream,支持链式调用,常见方法示例:filter(), map(), sorted(), distinct()。

        List<Integer> list = Arrays.asList(1, 2, 2,3);list.stream().distinct().forEach(System.out::println);//用于去除流中的重复元素。list.stream().map(x -> x * x).forEach(System.out::println);//用于对流中的每个元素应用一个函数,并返回一个新的流list.stream().filter(v->v==3).forEach(System.out::println);//用于对流中的元素进行筛选,只保留满足条件的元素list.stream().flatMap(s -> s.toString().chars().boxed()).forEach(System.out::println);//用于将流中的每个元素转换为另一个流,然后将这些流连接成一个流list.stream().limit(2).forEach(System.out::println);//用于限制流中元素的数量list.stream().skip(2).forEach(System.out::println);//用于跳过流中前n个元素list.stream().sorted().forEach(System.out::println);//用于对流中的元素进行排序

支持链式调用

        list.stream().distinct().filter(v->v==3).sorted().map(x -> x * x).forEach(System.out::println);

但是注意,流中间操作的方法返回的结果依然是流,但是上面为了显示这些方法使用的样例里面
forEach(System.out::println)这个是终止操作方法,也就是在forEach方法之前的返回的是流,在使用forEach方法之后返回的又将流转换非 Stream 结果

终止操作(Terminal Operations)

触发实际计算,返回非 Stream 结果(如集合、数值、void),常见方法示示例:collect(), forEach(), reduce(), count()

        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");names.stream().forEach(System.out::println);//对流中的每个元素执行指定的操作 这里是打印names.stream() .map(String::toUpperCase).collect(Collectors.toList()).forEach(System.out::println);//将流中的元素收集到一个容器中System.out.println(names.stream().allMatch(s -> s.contains("s")));//allMatch 检查是否匹配所有元素System.out.println(names.stream().anyMatch(s -> s.contains("a")));//anyMatch 检查是否至少匹配一个元素System.out.println(names.stream().noneMatch(s -> s.contains("x")));//noneMatch:检查是否没有匹配所有元素System.out.println(names.stream().findFirst());//findFirst:返回当前流中的第一个元素System.out.println(names.stream().findAny());//findAny:返回当前流中的任意元素System.out.println(names.stream().count());//count:返回流中元素总数System.out.println(names.stream().max(Comparator.comparingInt(s->s.length())));//max:返回流中最大值System.out.println(names.stream().min(Comparator.comparingInt(s->s.length())));//min:最小值

Stream 的流分类

顺序流(Sequential Stream)

默认模式:所有操作在单线程中按顺序执行

List<Integer> list = Arrays.asList(1, 2, 3);
Stream<Integer> stream = list.stream(); // 顺序流

适用场景:
数据量较小,或操作本身简单。
需要保证操作顺序(如 sorted() 依赖前序操作结果)。

并行流(Parallel Stream)

Stream<Integer> parallelStream = list.parallelStream(); // 并行流Stream<Integer> parallelStream = list.stream().parallel(); // 转换为并行流

适用场景:
数据量较大,且任务可独立拆分(无共享状态或顺序依赖)。
操作耗时(如复杂计算、I/O 等待)。

并行流的注意事项

1.线程安全问题
确保操作中使用的 Lambda 表达式或函数是线程安全的(避免共享可变状态)。
示例错误:

List<Integer> result = new ArrayList<>();
list.parallelStream().forEach(result::add); // 并发修改 ArrayList 导致数据错误

应使用线程安全的收集器(如 Collectors.toList()):

List<Integer> result = list.parallelStream().collect(Collectors.toList());

2.性能未必更好
并行流需额外开销(任务拆分、线程调度),对小数据量可能更慢。
测试性能:通过基准测试(如 JMH) 验证是否适合并行

3.顺序依赖操作
如 limit()、findFirst() 在并行流中可能性能更差,需改用无序流

list.parallelStream().unordered().limit(10); // 提升性能

ORDERED是Spliterator的特征值, 特征要求并行流保持元素顺序(如 List),改成unordered就是改成序列流,除此之外

并行流的底层机制

1.Spliterator
并行流通过 Spliterator(可拆分迭代器) 将数据源拆分为多个子任务,是 Stream API 并行处理的底层实现

List<String> list = Arrays.asList("Java", "Python", "C++", "Go");// 使用并行流处理
list.parallelStream() // 将数据源拆分为多个子任务.map(String::toUpperCase).forEach(System.out::println);// 输出(顺序不确定,因为并行处理):
// PYTHON
// JAVA
// GO
// C++

2.ForkJoinPool
并行流默认使用公共的 ForkJoinPool(线程数 = CPU 核心数)。通过系统属性修改默认线程池大小

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "8");

3.自定义线程池(避免影响全局)

ForkJoinPool customPool = new ForkJoinPool(4);
customPool.submit(() -> list.parallelStream().forEach(...)).get();

顺序流 vs 并行流的对比

特性顺序流并行流
线程模型单线程多线程(ForkJoinPool 默认线程池)
性能优势简单任务、小数据量大数据量、可并行化的复杂任务
开销高(线程切换、任务拆分/合并)
顺序保证严格按顺序处理不保证顺序(除非使用有序操作)
数据源要求无特殊要求数据源需可拆分(如 ArrayList

顺序流和并行流的示例代码

顺序流处理

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> filtered = names.stream().filter(name -> name.length() > 3).map(String::toUpperCase).collect(Collectors.toList()); // [ALICE, CHARLIE]

并行流处理

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = numbers.parallelStream()//通过底层Spliterator拆分为多个子任务.filter(n -> n % 2 == 0).mapToInt(n -> n * 2).sum(); // (2+4+6+8+10)*2 = 60

顺序流并行流总结

顺序流:简单、低开销,适合小数据量或顺序敏感操作。
并行流:通过多线程加速处理,适合大数据量和可并行化任务,但需注意线程安全和性能开销。

选择策略:
优先使用顺序流,仅在必要时(且验证有效)切换为并行流。
避免在并行流中操作共享可变状态。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/75405.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EAL4+ vs EAL7:高安全场景下的等级选择策略

在数字化浪潮席卷全球的当下&#xff0c;信息安全已然成为各行各业稳健发展的基石。特别是在高安全需求场景中&#xff0c;选择契合的安全等级成为保障信息资产安全的关键。EAL&#xff08;Evaluation Assurance Level&#xff09;评估保障级作为衡量信息技术产品安全保障能力的…

【Java集合】TreeSet、TreeMap源码解读

参考笔记&#xff1a;java TreeSet 和 TreeMap 源码解读-CSDN博客 目录 1.前言 2.红黑树 2.1 红黑树的五大性质 2.2 节点颜色的初始设置 2.3 插入新节后的调整 2.4 删除结构后的调整 2.5 排序规则 2.6 设计红黑树的原因 3.TreeSet简介、底层实现 3.1 TreeSet简介 3.…

【C++初学】C++核心编程技术详解(二):类与继承

函数提高 3.1 函数默认参数 函数的形参可以有默认值&#xff0c;调用时可以省略这些参数。 示例代码&#xff1a; int func(int a, int b 10, int c 10) {return a b c; }int main() {cout << "ret " << func(20, 20) << endl;cout <<…

Next.js + Droplet:高并发视频内容平台部署与优化扩展实战

在构建在线服务时&#xff0c;无论你是开发者还是企业技术负责人&#xff0c;扩展性和稳定性始终是绕不开的核心挑战。尤其在涉及高并发访问、大量数据传输和持续内容分发的场景中&#xff0c;系统架构的设计直接决定了用户体验与业务成效。 本文将以视频点播&#xff08;Video…

Python爬虫第13节-解析库pyquery 的使用

目录 前言 一、pyquery 初始化 1.1 字符串初始化 1.2 URL 初始化 1.3 文件初始化 二、基本 CSS 选择器 三、pyquery 查找节点 3.1 子节点 3.2 父节点 3.3 兄弟节点 四、遍历 五、获取信息 5.1 获取属性 5.2 获取文本 六、节点操作 6.1 addClass 和 removeClass…

【Hadoop入门】Hadoop生态之Pig简介

1 什么是Pig&#xff1f; 在大数据分析领域&#xff0c;Apache Pig是一个不可忽视的重要工具。Pig是Apache Hadoop生态系统中的一个高级数据分析平台&#xff0c;它提供了一种称为Pig Latin的脚本语言&#xff0c;用于简化大规模数据集的并行处理。Pig的核心思想是将复杂的数据…

python 语言 设计模式

python 语言 设计模式 设计模式是指在软件开发过程中,针对反复出现的问题所总结归纳出的通用解决方案。以下是一些常见的Python语言设计模式: 目录 python 语言 设计模式创建型模式结构型模式行为型模式创建型模式 单例模式 定义:保证一个类只有一个实例,并提供一个全局访…

QT QML布局

一、‌锚点布局(Anchors) 通过定义元素与其他元素或父容器的锚点关系实现定位,支持动态调整和边距控制‌。 Rectangle {anchors.left: parent.left // 左对齐父容器anchors.top: parent.top // 顶部对齐父容器anchors.margins: 10 // 统一设置四周边距width: …

【力扣03】无重复字符的最长子串

题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。示例 2: 输入: s "bbbbb" 输出: 1 解释:…

一文介绍阿里32B推理模型

什么是QwQ-32B&#xff1f; QwQ-32B并非普通的聊天机器人模型&#xff0c;而是推理模型。推理模型专注于逻辑拆解问题、分步推导&#xff0c;并输出结构化答案。 通过下面的示例&#xff0c;我们可以直观看到QwQ-32B的思考过程&#xff1a; qwq-32b思考过程 如果你需要写作辅…

AutoGen深度解析:从核心架构到多智能体协作的完整指南

AutoGen是微软推出的一个革命性多智能体(Multi-Agent)框架&#xff0c;它通过模块化设计和灵活的对话机制&#xff0c;极大地简化了基于大型语言模型(LLM)的智能体系统开发。本文将深入剖析AutoGen的两个核心模块——core基础架构和agentchat多智能体对话系统&#xff0c;带您全…

HTML的svg元素

<svg>元素 <svg>是一种用于描述二维矢量图形的 XML 格式&#xff0c;可以直接嵌入 HTML 文档中。 <svg>基本用法 <svg>的几种基本用法,包括圆形&#xff0c;正方形&#xff0c;三角形&#xff0c;直线 &#xff0c;折线等 <body><svg widt…

Qt 子项目依赖管理:从原理到实践的最佳分析:depends还是 CONFIG += ordered

1. 问题背景 在Qt项目开发中&#xff0c;当一个工程包含多个子项目&#xff08;如库、插件、测试模块&#xff09;时&#xff0c;如何正确管理它们的构建顺序和依赖关系&#xff1f; 如&#xff1a; 在开发一个包含核心库&#xff08;core&#xff09;、GUI模块&#xff08;g…

业务幂等性技术架构体系-接口幂等

接口幂等 对于幂等的考虑&#xff0c;主要解决两点前后端交互与服务间交互。这两点有时都要考虑幂等性的实现。从前端的思路解决 的话&#xff0c;主要有三种&#xff1a;前端防重、PRG模式、Token机制。 前端防重 通过前端防重保证幂等是最简单的实现方式&#xff0c;前端相关…

AI工具导航大全 | 2025精选版(持续更新)

&#x1f680; AI工具导航大全 | 2025精选版&#xff08;持续更新&#xff09; 更新日期&#xff1a;2025-04-11 | 适用场景&#xff1a;学术研究 | 办公提效 | 创意设计 | 开发编程 数据来源&#xff1a;综合高校实验室、企业实践及开发者社区推荐 &#x1f50d; 导航目录 &…

驱动-内核空间和用户空间数据交换

内核空间与用户控件数据交换 前面了解的字符设备中对 file_operations 结构体的进行了填充&#xff0c; 该 结构体的每一个成员都对应着一个系统调用&#xff0c; 例如 read、 write 等&#xff0c; 在字符设备相关的文章中有实验过对 调用函数进行了标志打印&#xff0c; 并没…

5G_WiFi_CE_DFS

目录 一、规范要求 1、法规目录 2、定义 3、运行模式 4、主/从设备相关的运行行为及具体的动态频率选择&#xff08;DFS&#xff09;要求 5、产品角色确定测试项目 6、测试项目 测试项1&#xff1a;信道可用性检查&#xff08;Channel Availability Check&#xff09; …

Devops之GitOps:什么是Gitops,以及它有什么优势

GitOps 定义 GitOps 是一种基于版本控制系统&#xff08;如 Git&#xff09;的运维实践&#xff0c;将 Git 作为基础设施和应用程序的唯一事实来源。通过声明式配置&#xff0c;系统自动同步 Git 仓库中的期望状态到实际运行环境&#xff0c;实现持续交付和自动化运维。其核心…

【蓝桥杯】单片机设计与开发,第十二届

/*头文件声明区*/ #include <STC15F2K60S2.H>//单片机寄存器头文件 #include <init.h>//初始化底层驱动头文件 #include <led.h>//led,蜂鸣器,继电器底层驱动头文件 #include <key.h>//按键底层驱动头文件 #include <seg.h>//数码管底层驱动头…

Vue3连接MQTT作为客户端

先下载依赖 npx --yes --registry https://registry.npmmirror.com npm install mqtt 在src的api创建 mes.js // 导入axios import axios from axios;// 定义一个变量,记录公共的前缀, baseURL const baseURL http://localhost:8080; const instance axios.create({ base…