Java 中 Stream 流的使用详解

Java 中 Stream 流的使用详解

什么是 Stream?

Stream 是 Java 8 引入的一种全新的操作集合的方式。它支持通过声明性方式对集合进行复杂的数据操作(如过滤、排序、聚合等),避免使用大量的 for 循环,提高代码的可读性和简洁性。

Stream 具有以下特点:

  • 惰性执行:流操作是延迟的,只有在需要时才会执行。
  • 链式操作:流的操作可以通过方法链的形式串联。
  • 不可变性:Stream 本身不会修改原始数据结构。

Stream 的核心操作

Stream 流的操作分为三类:

  1. 创建流:通过集合、数组或生成器创建流。
  2. 中间操作:对数据流进行加工,如 filtermapsorted 等。
  3. 终端操作:触发流的执行,如 collectforEachreduce 等。

创建 Stream

1. 从集合创建

List<String> list = List.of("Java", "Python", "C++");
Stream<String> stream = list.stream();

2. 从数组创建

String[] array = {"Apple", "Banana", "Orange"};
Stream<String> stream = Arrays.stream(array);

3. 使用生成器创建

Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);
infiniteStream.limit(5).forEach(System.out::println); // 输出:0, 2, 4, 6, 8

中间操作

1. filter:过滤数据

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
List<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());
System.out.println(evenNumbers); // 输出:[2, 4, 6]

2. map:映射转换

List<String> names = List.of("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream().map(String::length).collect(Collectors.toList());
System.out.println(nameLengths); // 输出:[5, 3, 7]

3. sorted:排序

List<String> fruits = List.of("Banana", "Apple", "Orange");
List<String> sortedFruits = fruits.stream().sorted().collect(Collectors.toList());
System.out.println(sortedFruits); // 输出:[Apple, Banana, Orange]

4. distinct:去重

List<Integer> numbers = List.of(1, 2, 2, 3, 4, 4, 5);
List<Integer> uniqueNumbers = numbers.stream().distinct().collect(Collectors.toList());
System.out.println(uniqueNumbers); // 输出:[1, 2, 3, 4, 5]

5. limitskip:截取和跳过

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
List<Integer> limitedNumbers = numbers.stream().limit(3).collect(Collectors.toList());
System.out.println(limitedNumbers); // 输出:[1, 2, 3]List<Integer> skippedNumbers = numbers.stream().skip(3).collect(Collectors.toList());
System.out.println(skippedNumbers); // 输出:[4, 5, 6]

终端操作

1. collect:收集结果

List<Integer> numbers = List.of(1, 2, 3, 4, 5);
Set<Integer> numberSet = numbers.stream().collect(Collectors.toSet());
System.out.println(numberSet); // 输出:[1, 2, 3, 4, 5]

2. forEach:遍历

List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);

3. reduce:聚合

List<Integer> numbers = List.of(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce(0, Integer::sum);
System.out.println(sum); // 输出:15

4. count:计数

List<String> items = List.of("Apple", "Banana", "Orange");
long count = items.stream().filter(item -> item.startsWith("A")).count();
System.out.println(count); // 输出:1

5. findFirstfindAny:查找元素

List<Integer> numbers = List.of(1, 2, 3, 4, 5);
Optional<Integer> firstEven = numbers.stream().filter(n -> n % 2 == 0).findFirst();
firstEven.ifPresent(System.out::println); // 输出:2

案例:复杂数据处理

数据准备

class Employee {String name;String department;double salary;Employee(String name, String department, double salary) {this.name = name;this.department = department;this.salary = salary;}
}List<Employee> employees = List.of(new Employee("Alice", "HR", 5000),new Employee("Bob", "IT", 7000),new Employee("Charlie", "IT", 6000),new Employee("David", "Finance", 8000)
);

1. 查找 IT 部门的员工姓名

List<String> itEmployees = employees.stream().filter(emp -> "IT".equals(emp.department)).map(emp -> emp.name).collect(Collectors.toList());
System.out.println(itEmployees); // 输出:[Bob, Charlie]

2. 按部门分组员工

Map<String, List<Employee>> groupedByDept = employees.stream().collect(Collectors.groupingBy(emp -> emp.department));
System.out.println(groupedByDept);

3. 计算所有员工的平均工资

double averageSalary = employees.stream().mapToDouble(emp -> emp.salary).average().orElse(0);
System.out.println(averageSalary); // 输出:6500.0

注意事项

  1. 避免修改流中的元素:Stream 是不可变的,避免在流中修改元素。
  2. 流的惰性求值:中间操作只有在终端操作时才会执行。
  3. 不要重复消费流:流一旦操作完成,就不能再次使用。


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

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

相关文章

AMD | GPU | 深度学习 | 如何使用

问题&#xff1a;我在复现代码的时候&#xff0c;发现自己只拥有AMD的GPU&#xff0c;对于一个硬件小白来说&#xff0c;怎么办呢&#xff1f;我想看看怎么使用&#xff1b;解决&#xff1a; 首先要安装支持AMD的GPU的pytorch&#xff0c;pytorch&#xff1b; 使程序在安装了支…

Blender高效优化工作流程快捷小功能插件 Haggis Tools V1.1.5

Haggis Tools V1.1.5 是一款专为Blender设计的插件&#xff0c;旨在优化工作流程、减少单调和重复的任务&#xff0c;从而为艺术家节省时间。这款插件适用于多个版本的Blender&#xff0c;能够有效提升工作效率。 Blender插件特点&#xff1a; 工作流程优化&#xff1a;专门设…

数据采集背后的效率革命:如何优化你的爬虫性能

在爬虫技术日益发展的今天&#xff0c;性能优化成为提升数据采集效率的关键。面对日益复杂的网页结构和庞大的数据量&#xff0c;高效的爬虫能够显著降低运行时间和资源成本。本文将围绕爬虫性能优化的核心方法展开讨论&#xff0c;并通过实例对比多进程、多线程以及普通爬取的…

OpenHarmony-5.PM 子系统(2)

电池服务组件OpenHarmony-4.1-Release 1.电池服务组件 Battery Manager 提供了电池信息查询的接口&#xff0c;同时开发者也可以通过公共事件监听电池状态和充放电状态的变化。电池服务组件提供如下功能&#xff1a; 电池信息查询。充放电状态查询。关机充电。 电池服务组件架…

测试冰淇淋模型

测试领域的冰淇淋模型&#xff08;Ice Cream Cone Model&#xff09;是一个相对于传统的测试金字塔模型的反转&#xff0c;是一种与经典金字塔模型相对的测试策略。在这种模型中&#xff0c;测试的分布和重点与传统金字塔模型相反。以下是冰淇淋模型的主要特点和原因&#xff1…

短视频矩阵账号管理技术源码搭建详解,支持OEM

一、引言 在短视频矩阵系统中&#xff0c;账号管理是至关重要的一环&#xff0c;它涉及到多平台账号的接入、用户信息的安全存储与高效管理、权限的精准控制以及账号数据的同步与更新等关键功能。一个健壮、灵活且安全的账号管理技术架构&#xff0c;能够为整个短视频矩阵系统的…

【驱动开发】设备分类、设备号申请和注销,注册和移除字符设备,以及一个基本的内核驱动程序框架代码

一、Linux内核对设备的分类 Linux的文件种类 序号符号类型文件内容文件名原信息1-普通文件√√√2d目录文件√√√3p管道文件√√4s本地socket文件√√5l链接文件软链接有;硬链接相当于别名√√6c字符设备√√7b块设备√√设备类型 Linux内核按驱动程序实现模型框架的不同,…

黑马Java面试教程_P2_MySQL

系列博客目录 文章目录 系列博客目录前言1. 优化1.1 MySQL中&#xff0c;如何定位慢查询&#xff1f;面试文稿 1.2 面试官接着问&#xff1a;那这个SQL语句执行很慢,如何分析 ( 如何优化&#xff09;呢?面试文稿 1.3 了解过索引吗?(什么是索引)1.4 继续问 索引的底层数据结构…

Learning Multi-Scale Photo Exposure Correction

Abstract 用错误的曝光捕捉照片仍然是相机成像的主要错误来源。曝光问题可分为以下两类:(i)曝光过度&#xff0c;即相机曝光时间过长&#xff0c;导致图像区域明亮和褪色;(ii)曝光不足&#xff0c;即曝光时间过短&#xff0c;导致图像区域变暗。曝光不足和曝光过度都会大大降低…

湖南引力:低代码助力实现智慧养老管理系统

“低代码开发宛如一座神奇的桥梁&#xff0c;它以简洁高效的方式连接起创意与应用&#xff0c;降低了开发门槛&#xff0c;为企业和开发者带来前所未有的便捷与可能&#xff0c;开启了快速实现软件梦想的新征程。” ——王港&#xff0c;湖南引力科技有限公司 湖南引力科技有…

uniapp中wx.getFuzzyLocation报错如何解决

一、用wx.getLocation接口审核不通过 用uniapp开发小程序时难免需要获取当前地理位置。 代码如下&#xff1a; uni.getLocation({type: wgs84,success: function (res) {console.log(当前位置的经度&#xff1a; res.longitude);console.log(当前位置的纬度&#xff1a; r…

【探花交友】day03—MongoDB基础

目录 课程介绍 1、通用设置 1.1 需求分析 1.2 查询通用设置 1.2 陌生人问题 1.3 通知设置 1.4 黑名单管理 2、MongoDB简介 1.1、MongoDB简介 1.2、MongoDB的特点 1.3 数据类型 3、MongoDB入门 2.1、数据库以及表的操作 2.2、新增数据 2.3、更新数据 2.4、删除数…

编程考古-传奇的开始Delphi(下)含所有版本.iso

概览 Delphi 的最新版本&#xff0c;即 Delphi 12&#xff0c;勾勒出了自公司创立以来的一条进化之路。该平台不断通过提升开发者生产力、扩展其支持的平台范围以及引入前沿技术来实现自我完善。作为 Embarcadero 提供的主要快速应用开发&#xff08;RAD&#xff09;环境&…

Debian安装配置RocketMQ

安装配置 本次安装在/tools/rocket目录下 下载 wget https://dist.apache.org/repos/dist/release/rocketmq/5.3.1/rocketmq-all-5.3.1-bin-release.zip 解压缩 unzip rocketmq-all-5.3.1-bin-release.zip 如果出现以下报错 -bash: unzip: command not found可安装unzip工具后执…

MyBatis知识点笔记

目录 mybatis mapper-locations的作用&#xff1f; mybatis configuration log-impl 作用&#xff1f; resultType和resultMap的区别&#xff1f; 参数 useGeneratedKeys &#xff0c;keyColumn&#xff0c;keyProperty作用和用法 取值方式#和$区别 动态标签有哪些 MyBat…

20241218-信息安全理论与技术复习题

20241218-信息安全理论与技术复习题 一、习题1 信息安全的基本属性是&#xff08;D )。 A、机密性 B、可用性 C、完整性 D、上面 3 项都是 “会话侦听和劫持技术” 是属于&#xff08;B&#xff09;的技术。 A、 密码分析还原 B、 协议漏洞渗透 C、 应用漏洞分析与渗透 D、 D…

顶顶通呼叫中心中间件的三种呼叫方式(mod_cti基于FreeSWITCH)

顶顶通呼叫中心共有三种呼叫方式&#xff1a; 手拨呼叫点击呼叫自动外呼 联系我们 有意向了解呼叫中心中间件的用户&#xff0c;可以点击该链接添加工作人员&#xff1a;https://blog.csdn.net/H4_9Y/article/details/136148229 手拨呼叫 手拨呼叫属于常规的呼叫方式&…

C 语言中 strlen 函数的深入剖析

目录 一、strlen 函数的基本介绍 二、strlen 函数的工作原理 三、strlen 函数的使用注意事项 四、strlen 与其他字符串处理函数的结合使用 五、strlen 在实际编程中的应用场景 六、总结 在 C 语言的编程世界里&#xff0c;strlen函数是一个经常被使用但又容易被误解的重要…

Redis 实战篇 ——《黑马点评》(上)

《引言》 在进行了前面关于 Redis 基础篇及其客户端的学习之后&#xff0c;开始着手进行实战篇的学习。因内容很多&#xff0c;所以将会分为【 上 中 下 】三篇记录学习的内容与在学习的过程中解决问题的方法。Redis 实战篇的内容我写的很详细&#xff0c;为了能写的更好也付出…

文档解析丨高效准确的PDF解析工具,赋能企业非结构化数据治理

在数据为王的时代浪潮中&#xff0c;企业数据治理已成为组织优化运营、提高竞争力的关键。随着数字化进程的加速&#xff0c;企业所积累的数据量呈爆炸式增长&#xff0c;数据类型也愈发多样化&#xff0c;这些数据构成了现代企业数据资产的重要组成部分。 然而&#xff0c;传…