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

java的Stream流处理

Java Stream 流处理详解

Stream 是 Java 8 引入的一个强大的数据处理抽象,它允许你以声明式方式处理数据集合(类似于 SQL 语句),支持并行操作,提高了代码的可读性和处理效率。

一、Stream 的核心概念

1. 什么是 Stream

  • 不是数据结构:不存储数据,只是从数据源(集合、数组等)获取数据

  • 函数式风格:支持 lambda 表达式和方法引用

  • 延迟执行:许多操作(中间操作)不会立即执行,只有遇到终止操作才会执行

  • 可消费性:Stream 只能被消费一次,用完即失效

2. 操作类型

  • 中间操作(Intermediate Operations):返回 Stream 本身,可以链式调用(如 filter, map)

  • 终止操作(Terminal Operations):产生最终结果或副作用(如 forEach, collect)

二、创建 Stream 的多种方式

// 1. 从集合创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream1 = list.stream();       // 顺序流
Stream<String> parallelStream = list.parallelStream(); // 并行流// 2. 从数组创建
String[] array = {"a", "b", "c"};
Stream<String> stream2 = Arrays.stream(array);// 3. 使用Stream.of()
Stream<String> stream3 = Stream.of("a", "b", "c");// 4. 使用Stream.generate() 无限流
Stream<Double> randomStream = Stream.generate(Math::random).limit(5);// 5. 使用Stream.iterate() 迭代流
Stream<Integer> iterateStream = Stream.iterate(0, n -> n + 2).limit(10);

三、常用的中间操作

1. 过滤操作

// filter(Predicate) 过滤符合条件的元素
List<String> filtered = list.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList());

2. 映射操作

// map(Function) 将元素转换为其他形式
List<Integer> lengths = list.stream().map(String::length).collect(Collectors.toList());// flatMap 将多个流合并为一个流
List<String> flatMapped = list.stream().flatMap(s -> Stream.of(s.split(""))).collect(Collectors.toList());

3. 去重和排序

// distinct() 去重
List<String> distinct = list.stream().distinct().collect(Collectors.toList());// sorted() 自然排序
List<String> sorted = list.stream().sorted().collect(Collectors.toList());// sorted(Comparator) 自定义排序
List<String> customSorted = list.stream().sorted((s1, s2) -> s2.compareTo(s1)).collect(Collectors.toList());

4. 其他中间操作

// limit(long) 限制元素数量
// skip(long) 跳过前N个元素
// peek(Consumer) 查看流中元素(主要用于调试)

四、常用的终止操作

1. 遍历操作

// forEach(Consumer) 遍历每个元素
list.stream().forEach(System.out::println);

2. 收集结果

// collect(Collector) 将流转换为集合或其他形式
List<String> collectedList = stream.collect(Collectors.toList());
Set<String> collectedSet = stream.collect(Collectors.toSet());
Map<String, Integer> map = stream.collect(Collectors.toMap(Function.identity(), String::length));

3. 聚合操作

// count() 计数
long count = list.stream().count();// max/min(Comparator) 最大/最小值
Optional<String> max = list.stream().max(Comparator.naturalOrder());// reduce 归约操作
Optional<Integer> sum = Stream.of(1, 2, 3).reduce(Integer::sum);

4. 匹配操作

// anyMatch 任意元素匹配
boolean anyStartsWithA = list.stream().anyMatch(s -> s.startsWith("a"));// allMatch 所有元素匹配
boolean allStartsWithA = list.stream().allMatch(s -> s.startsWith("a"));// noneMatch 没有元素匹配
boolean noneStartsWithZ = list.stream().noneMatch(s -> s.startsWith("z"));

五、数值流特化

Java 8 提供了专门的数值流,避免装箱拆箱开销:

// IntStream, LongStream, DoubleStream
IntStream intStream = IntStream.range(1, 100); // 1-99
DoubleStream doubleStream = DoubleStream.of(1.1, 2.2);// 常用数值操作
int sum = IntStream.rangeClosed(1, 100).sum(); // 1-100的和
OptionalDouble avg = IntStream.of(1, 2, 3).average();

六、并行流处理

// 创建并行流
List<String> parallelProcessed = list.parallelStream().filter(s -> s.length() > 1).collect(Collectors.toList());// 注意事项:
// 1. 确保操作是线程安全的
// 2. 避免有状态的操作
// 3. 数据量足够大时才使用并行流

七、收集器(Collectors)的高级用法

// 分组
Map<Integer, List<String>> groupByLength = list.stream().collect(Collectors.groupingBy(String::length));// 分区
Map<Boolean, List<String>> partition = list.stream().collect(Collectors.partitioningBy(s -> s.startsWith("a")));// 连接字符串
String joined = list.stream().collect(Collectors.joining(", "));// 汇总统计
IntSummaryStatistics stats = list.stream().collect(Collectors.summarizingInt(String::length));

八、实际应用示例

示例1:处理对象集合

List<Person> people = ...;// 获取所有成年人的姓名列表
List<String> adultNames = people.stream().filter(p -> p.getAge() >= 18).map(Person::getName).collect(Collectors.toList());// 按城市分组
Map<String, List<Person>> byCity = people.stream().collect(Collectors.groupingBy(Person::getCity));// 计算每个城市的平均年龄
Map<String, Double> avgAgeByCity = people.stream().collect(Collectors.groupingBy(Person::getCity,Collectors.averagingInt(Person::getAge)));

示例2:文件处理

// 读取文件并处理
try (Stream<String> lines = Files.lines(Paths.get("data.txt"))) {long wordCount = lines.flatMap(line -> Arrays.stream(line.split("\\s+"))).filter(word -> word.length() > 0).count();
} catch (IOException e) {e.printStackTrace();
}

九、注意事项

  1. 流只能消费一次:尝试第二次使用已关闭的流会抛出 IllegalStateException

  2. 避免修改源数据:流操作期间不应修改源集合

  3. 合理使用并行流:并非所有情况都适合并行,小数据量可能适得其反

  4. 注意自动装箱:数值操作尽量使用原始类型特化流(IntStream等)

  5. 延迟执行特性:没有终止操作,中间操作不会执行

Stream API 提供了一种高效、声明式的数据处理方式,是现代 Java 编程中不可或缺的工具。合理使用可以大幅提升代码的可读性和维护性。

相关文章:

java的Stream流处理

Java Stream 流处理详解 Stream 是 Java 8 引入的一个强大的数据处理抽象&#xff0c;它允许你以声明式方式处理数据集合&#xff08;类似于 SQL 语句&#xff09;&#xff0c;支持并行操作&#xff0c;提高了代码的可读性和处理效率。 一、Stream 的核心概念 1. 什么是 Str…...

C PRIMER PLUS——第9节:动态内存分配、存储类别、链接和内存管理

目录 1.动态内存分配 1.1 malloc 函数 1.2 calloc 函数 1.3 realloc 函数 1.4 free 函数 1.5常见错误 1.6综合例题 2.C语言的内存结构 3.存储类别 3.1作用域&#xff08;Scope&#xff09; 3.2链接&#xff08;Linkage&#xff09; 3.3存储期&#xff08;Storage Du…...

作业...

基础配置 RI R2 R3 R4 R5 例如R1 BGP配置 1,R1和R2之间使用直连接口IP地址来建立EBGP对等体关系 2、R2、R3、R4之间配置OSPF协议&#xff0c;保证各设备之间的网络互通&#xff0c;且通过重发布的方式发布路由 查看R2、R3、R4的OSPF路由表&#xff1a; \ R2、R3、R4使用环…...

IC ATE集成电路测试学习——电流测试的原理和方法

电流测试 我们可以通过电流来判断芯片的工作状态时&#xff0c;首先先了解下芯片的电流是如何产生的。 静态电流 理论上&#xff0c;CMOS结构的芯片静态时几乎不耗电 CMOS基本结构&#xff1a;Pmos Nmos 串联当逻辑电平稳定时&#xff1a; ➜ 要么Pmos导通&#xff0c;Nmo…...

redis数据结构-03 (HMSET、HGET、HGETALL)

Redis 哈希介绍&#xff1a;HMSET、HGET、HGETALL Redis 哈希是一种强大的数据结构&#xff0c;允许您在单个键内存储字段值对的集合。它们对于表示对象、配置或任何可以自然分组到字段中的数据非常有用。本课将向您介绍使用 Redis 哈希的基本命令&#xff1a; HMSET 、 HGET …...

2025年01月09日德美医疗前端面试

目录 vue2 的双向绑定的原理vue3 的双向绑定原理vue 的生命周期vue 子组件为何不能修改父组件的值js delete 删除数组的某一个值会怎么样vue 和 react 的 diff 算法什么是闭包原型链this指向 vue2 的双向绑定的原理 以下是 Vue 2 双向绑定的原理&#xff1a; 1. 核心概念 …...

快速理解动态代理

什么是动态代理(Java核心技术卷1的解释) 动态代理是一种运行时生成代理对象的技术&#xff0c;其本质是通过字节码增强在不修改原始类代码的前提下&#xff0c;动态拦截并扩展目标对象的行为。它通过代理对象对原始方法的调用进行拦截&#xff0c;并在方法执行前后注入自定义逻…...

实战演练:用 AWS Lambda 和 API Gateway 构建你的第一个 Serverless API

实战演练:用 AWS Lambda 和 API Gateway 构建你的第一个 Serverless API 理论千遍,不如动手一遍!在前面几篇文章中,我们了解了 Serverless 的概念、FaaS 的核心原理以及 BaaS 的重要作用。现在,是时候把这些知识运用起来,亲手构建一个简单但完整的 Serverless 应用了。 …...

spark算子介绍

目录 1. 转换算子&#xff08;Transformation&#xff09;1.1 常用转换算子 2. 行动算子&#xff08;Action&#xff09;2.1 常用行动算子 3. 转换算子与行动算子的区别4. 示例代码5. 总结 在Spark中&#xff0c;算子&#xff08;Operator&#xff09;是对数据集&#xff08;RD…...

AugmentCode 非常昂贵的新定价

AugmentCode 现在的价格比 Cursor 和 Windsurf 的总和还要贵。 AugmentCode 曾是我开发工作流程的常用工具。出乎意料的是,他们改变了定价结构,让开发者们震惊不已。 原来的30 美元月费已经增长为50 美元月费,这是一个67%的增长。 改变我看法的不仅仅是价格上涨,还有他…...

前端面试2

1. 面试准备 1. 建立自己的知识体系 思维导图ProcessOn框架Vue elementUI自查 https://zh.javascript.info/ 借鉴 https://juejin.cn/post/6844904103504527374http://conardli.top/blog/article/https://github.com/mqyqingfeng/Bloghttp://47.98.159.95/my_blog/#html 2.技能…...

大疆卓驭嵌入式面经及参考答案

FreeRTOS 有哪 5 种内存管理方式&#xff1f; heap_1.c&#xff1a;这种方式简单地在编译时分配一块固定大小的内存&#xff0c;在整个运行期间不会进行内存的动态分配和释放。它适用于那些对内存使用需求非常明确且固定&#xff0c;不需要动态分配内存的场景&#xff0c;优点是…...

RAID磁盘阵列的概念(自用留档)

概念 RAID磁盘阵列是由若干个磁盘组成的磁盘组。 磁盘组可以恢复意外丢失的数据&#xff0c;保证了数据的安全性。 种类 根据实际情况的不同&#xff0c;RAID有若干种&#xff0c;以一个具有三块硬盘的硬盘组为例&#xff1a; RAID 0&#xff1a;将文件拆分成三份分别放到三…...

设计模式简述(十八)享元模式

享元模式 描述基本组件使用 描述 当内存中存在大量类似的对象时&#xff0c;可以考虑使用享元模式减少整体内存占用。 可以将相同的部分和不同的部分进行拆分&#xff0c;以达到多个对象共享相同部分内存的目的。 基本组件 通常享元对象通过共享的属性映射一个享元对象。 公…...

架构进阶:74页数据架构设计总体规划方案【附全文阅读】

本文讨论了数据资源规划在信息化战略规划中的重要性&#xff0c;详细阐述了数据资源规划的方法与过程&#xff0c;包括系统架构、业务能力模型、数据架构等。 文章指出&#xff0c;数据资源规划需要梳理企业级数据模型&#xff0c;明确数据分布和流向&#xff0c;建立统一的数据…...

情书大全v3.0.1

《情书大全》是一款致力于情书写作的手机应用程序&#xff0c;内置了丰富的情书范本及定制化服务。用户无论是想要倾诉爱意、交流友情还是传递亲情&#xff0c;都能在这款应用中寻得合适的情书样本。用户还可以根据自己的需求对模板进行编辑和调整&#xff0c;轻松创作出感人至…...

基于OpenCV的人脸识别:LBPH算法

文章目录 引言一、概述二、代码实现1. 代码整体结构2. 导入库解析3. 训练数据准备4. 标签系统5. 待识别图像加载6. LBPH识别器创建7. 模型训练8. 预测执行9. 结果输出 三、 LBPH算法原理解析四、关键点解析五、改进方向总结 引言 人脸识别是计算机视觉领域的一个重要应用&…...

鸿蒙 使用动画 简单使用

鸿蒙 使用动画 简单使用 动画就两个&#xff0c;属性动画和转场动画 属性动画只是组件的属性发生变化&#xff0c;而转场动画是指对将要出现或消失的组件做动画&#xff0c;而文档的其他动画只是给这两个动画效果锦上添花罢了 这篇文章简单介绍这两个动画&#xff0c;其他的…...

MySQL数据库迁移SQL语句指南

MySQL数据库迁移SQL语句指南 一、基础迁移方法 1. 使用mysqldump进行全量迁移 -- 导出源数据库&#xff08;在命令行执行&#xff09; mysqldump -u [源用户名] -p[源密码] --single-transaction --routines --triggers --events --master-data2 [数据库名] > migration…...

arcgis和ENVI中如何将数据输出为tif

一、arcgis中转换为tif 右键图层&#xff1a; Data -> Export Data, 按照图示进行选择&#xff0c;选择tiff格式导出即可&#xff0c;还可以选择其他类型的格式&#xff0c;比如envi。 二、 ENVI中转换为tif File -> Save As -> Save As (ENVI, NITF, TIFF, DTED) …...

RagFlow 完全指南(一):从零搭建开源大模型应用平台(Ollama、VLLM本地模型接入实战)

文章目录 1. 相关资源2. 核心特性3. 安装与部署3.1 环境准备3.2 部署RagFlow3.3 更新RagFlow3.4 系统配置 4. 接入本地模型4.1 接入 Ollama 本地模型4.1.1 步骤4.1.2 常见问题 4.2 接入 VLLM 模型 5. 应用场景6. 总结 1. 相关资源 官网GitHub文档中心 2. 核心特性 &#x1f…...

计算机网络 4-2-1 网络层(IPv4)

2 IPv4分组 各协议之间的关系 IP协议(Internet Protocol, 网际协议)是互联网的核心&#xff01; ARP协议用于查询同一网络中的<主机IP地址&#xff0c;MAC地址>之间的映射关系 ICMP协议用于网络层实体之间相互通知“异常事件” IGMP协议用于实现IP组播 2.1 结构<首…...

Python赋能自动驾驶:如何打造高效的环境感知系统

Python赋能自动驾驶:如何打造高效的环境感知系统 大家好,我是 Echo_Wish,今天我们来聊聊自动驾驶里的“眼睛”——环境感知系统,以及如何用 Python 实现它。 自动驾驶的核心目标是让车辆在没有人工干预的情况下安全行驶,而要做到这一点,环境感知系统必须实时获取并理解…...

ST表(稀疏表)

对ST表进行一个简单的总结&#xff0c;它可以实现O(1)的静态区间查询&#xff0c;可以适用于查询操作频繁但数据不修改的场景 题目来源 https://www.luogu.com.cn/problem/P3865 题目介绍 给定一个长度为 N 的数列&#xff0c;和 M 次询问&#xff0c;求出每一次询问的区间…...

Java常用类-比较器

目录 一、为什么需要比较器&#xff1f;二、核心差异速记表三、Comparable&#xff1a;对象自带的 “默认规则”1. 核心作用2. 源码定义3. 实战&#xff1a;给Student类加默认规则4. 源码验证&#xff08;以Integer为例&#xff09; 四、Comparator&#xff1a;临时的 “外部规…...

Python----机器学习(模型评估:准确率、损失函数值、精确度、召回率、F1分数、混淆矩阵、ROC曲线和AUC值、Top-k精度)

一、模型评估 1. 准确率&#xff08;Accuracy&#xff09;&#xff1a;这是最基本的评估指标之一&#xff0c;表示模型在测试集上正确 分类样本的比例。对于分类任务而言&#xff0c;准确率是衡量模型性能的直观标准。 2. 损失函数值&#xff08;Loss&#xff09;&#xff1…...

Linux工作台文件操作命令全流程解析(高级篇之vim和nano精讲)

全文目录 1 简单易用的 Nano (入门之选)1.1 适用场景1.2 安装命令1.3 基础操作1.4 优点 2 功能强大的 Vim2.1 适用场景2.2 安装命令2.3 模式说明‌2.4 常用命令2.4.1 普通模式2.4.2 编辑模式2.4.3 可视模式2.4.4 命令行模式 3 参考文献 写在前面 作为运维或者研发&#xff0c;日…...

大数据产品销售数据分析:基于Python机器学习产品销售数据爬虫可视化分析预测系统设计与实现

文章目录 大数据产品销售数据分析&#xff1a;基于Python机器学习产品销售数据爬虫可视化分析预测系统设计与实现一、项目概述二、项目说明三、研究意义四、系统总体架构设计总体框架技术架构数据可视化模块设计图后台管理模块设计数据库设计 五、开发技术介绍Flask框架Python爬…...

VS2022 Qt配置Qxlsx

目录 1、下载QXlsx&#xff0c;并解压文件夹 ​编辑2、打开VS2022配置QXlsx 3、VS配置Qxslx库 方法一&#xff1a;常规方法 方法二&#xff1a;直接使用源码 方法三&#xff1a;将QXlsx添加到Qt安装目录&#xff08;暂时尝试未成功&#xff09; 1、下载QXlsx&#xff0c;…...

OSPF案例

拓扑图&#xff1a; 要求&#xff1a; 1&#xff0c;R5为ISP&#xff0c;其上只能配置IP地址&#xff1b;R4作为企业边界路由器&#xff0c; 出口公网地址需要通过PPP协议获取&#xff0c;并进行chap认证 2&#xff0c;整个OSPF环境IP基于172.16.0.0/16划分&#xff1b;…...