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 编程中不可或缺的工具。合理使用可以大幅提升代码的可读性和维护性。

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

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

相关文章

llama-Factory不宜直接挂接Ollama的大模型

前言 llama-Factory尝试使用Ollama本地安装的大模型。 一、在Ollama中安装QWen 安装qwen:0.5b 安装完成了&#xff1a; 同理安装qwen2.5:0.5b 安装完毕后&#xff0c;再用ollama list进行查看&#xff1a; 我们在chatbox中进行查看&#xff1a; 说明这两个大模型&#xff0c;…

基于WSL用MSVC编译ffmpeg7.1

在windows平台编译FFmpeg&#xff0c;网上的大部分资料都是推荐用msys2mingw进行编译。在win10平台&#xff0c;我们可以采用另一种方式&#xff0c;即wslmsvc 实现window平台的ffmpeg编译。 下面将以vs2022ubuntu22.04 为例&#xff0c;介绍此方法 0、前期准备 安装vs2022 &…

vue3+vite项目引入tailwindcss

从2025年1月tailwindcss4.0发布开始使用tailwindcss比之前简化很多 1,安装 yarn add tailwindcss tailwindcss/vite2,配置vite.config.js import tailwindcss from tailwindcss/vite;...plugins: [tailwindcss(),...] ...3,在主css文件顶部添加 注意一定是css文件,不能是sc…

蓝牙RFCOMM协议概述

RFCOMM概述 概念 RFCOMM 协议提供了对 L2CAP 协议上的串行端口的模拟。该协议基于 ETSI 标准 GSM 07.10。 RFCOMM 采用与 TS07.10 相同的字节序列方式。所有二进制数字都按照从低位到高位的顺序&#xff0c;从左至右读。 两个使用RFCOMM通信的蓝牙设备可以打开多个仿真串行端…

[工具]B站缓存工具箱 (By 郭逍遥)

&#x1f4cc; 项目简介 B站缓存工具箱是一个多功能的B站缓存工具&#xff0c;包含视频下载、缓存重载、文件合并及系统设置四大核心功能。基于yutto开发&#xff0c;采用图形化界面操作&#xff0c;极大简化B站资源获取与管理流程。 工具可以直接将原本缓存的视频读取&#…

算法训练营第十三天|226.翻转二叉树、101. 对称二叉树、 104.二叉树的最大深度、111.二叉树的最小深度

递归 递归三部曲&#xff1a; 1.确定参数和返回值2.确定终止条件3.确定单层逻辑 226.翻转二叉树 题目 思路与解法 第一想法&#xff1a; 递归&#xff0c;对每个结点进行反转 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, le…

sunset:Solstice靶场

sunset:Solstice https://www.vulnhub.com/entry/sunset-solstice,499/ 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182&#xff0c;靶场IP192.168.23.244 3&#xff…

AZScreenRecorder最新版:功能强大、操作简便的手机录屏软件

AZScreenRecorder最新版是一款功能强大的手机录屏软件&#xff0c;专为安卓设备设计。它无需ROOT权限&#xff0c;支持无限录制时长&#xff0c;操作简单&#xff0c;录制过程中可以随时暂停&#xff0c;满足不同用户的个性化录屏需求。此外&#xff0c;用户还可以自定义分辨率…

模块自动导入的小工具

import { ref, reactive, onMounted } from vue import { useRoute, useRouter } from vue-router项目里很多文件都需要引入这些公共库&#xff0c;比较繁琐&#xff0c;使用一个小工具可以自动导入&#xff0c;就不需要在每个文件里面都写这些导入的代码了。 通过命令行下载安…

【读书笔记】《编码:隐匿在计算机软硬件背后的语言》01 逻辑与开关

【读书笔记】《编码&#xff1a;隐匿在计算机软硬件背后的语言》01 逻辑与开关 前言01 逻辑与开关 前言 我是一名光学工程专业研二的学生&#xff0c;目前正处于找工作的阶段&#xff0c;根据往年师兄师姐找工作的情况&#xff0c;在西安这个城市不出意外我能找到的应该就是嵌入…

TXT编码转换工具iconv

iconv.exe是实现TXT编码转换的命令行工具&#xff0c;支持几百种编码格式的转换&#xff0c;利用它可以在自主开发程序上实现TXT文档编码的自动转换。 一、命令参数格式 Usage: iconv [-c] [-s] [-f fromcode] [-t tocode] [file ...] or: iconv -l 二、转换的示例 将UTF-8…

软考中级数据库备考-上午篇

背景 新工作主要做大数据平台&#xff0c;考一个软考中级数据库系统工程师&#xff0c;补足一下基础知识。 基础知识 1.计算机硬件基础知识 正确答案:C 正确答案:D 正确答案:C 正确答案&#xff1a;BC 正确答案&#xff1a;B 正确答案:D 正确答案:A DMA建立内存与外设的直接…

AtCoder AT_abc405_d ABC405D - Escape Route

前言 BFS 算法在 AtCoder 比赛中还是会考的&#xff0c;因为不常练习导致没想到&#xff0c;不仅错误 TLE 了很多&#xff0c;还影响了心态&#xff0c;3 发罚时后才 AC。 思路 首先&#xff0c;我们把所有位置和出口的距离算出来&#xff08;用 BFS&#xff09;&#xff0c…

【计算机视觉】目标检测:yoloV1~yoloV11项目论文及对比

以下是 YOLO (You Only Look Once) 系列模型从 V1 到 V11 的详细介绍和项目地址&#xff08;截至2024年7月&#xff09;。YOLO 是目标检测领域的里程碑模型&#xff0c;以其 实时性 和 高精度 著称&#xff0c;广泛应用于自动驾驶、安防监控、工业检测等领域。 YOLOv1 (2016) …

推荐系统架构设计

1.分析用户行为数据​&#xff1a;​ 收集用户的活跃时间、点击行为、浏览历史等数据。​分析用户的活跃模式&#xff0c;确定用户最活跃的时间段。​kafka flink 数据库 分析用户行为并存储 2. 预生成推荐内容​&#xff1a;​ 在用户活跃时间之前&#xff0c;预先生成推荐…

BERT类模型

1. BERT类模型是否需要处理 [CLS] 或池化&#xff1f; 那首先搞懂 [CLS] 和池化 &#xff08;1&#xff09;[CLS] 的作用 BERT 的输入格式中&#xff0c;每个序列的开头会添加一个特殊的 [CLS] Token&#xff08;Classification Token&#xff09;。它的设计初衷是为分类任务…

我的世界云端服务器具体是指什么?

我的世界云端服务器是指一种基于互联网的多人游戏服务器&#xff0c;将游戏服务器运行在云平台上&#xff0c;而不是在本地计算机中&#xff0c;这使用户不需要考虑自身电脑的性能和网络稳定性&#xff0c;只需要通过网络连接到云端服务器&#xff0c;就可以享受到顺畅的游戏体…

软考(信息系统运行管理员)

第一章 信息系统运维概述 1.1 信息系统概述 信息的含义和类型 信息的含义&#xff1a; 一般&#xff1a;人们关心的事情的消息或知识。香农&#xff08;信息论创始人&#xff09;&#xff1a;用来减少随机不确定性的东西&#xff08;标志着信息科学进入定量研究阶段&#xff…

Unity基础学习(九)输入系统全解析:鼠标、键盘与轴控制

目录 一、Input类 1. 鼠标输入 2. 键盘输入 3. 默认轴输入 &#xff08;1&#xff09; 基础参数 &#xff08;2&#xff09;按键绑定参数 &#xff08;3&#xff09;输入响应参数 &#xff08;4&#xff09;输入类型与设备参数 &#xff08;5&#xff09;不同类型轴的参…

VBA将PDF文档内容逐行写入Excel

VBA是无法直接读取PDF文档的&#xff0c;但结合上期我给大家介绍了PDF转换工具xpdf-tools-4.05&#xff0c;先利用它将PDF文档转换为TXT文档&#xff0c;然后再将TXT的内容写入Excel&#xff0c;这样就间接实现了将PDF文档的内容导入Excel的操作。下面的代码将向大家演示如何实…