Java Stream介绍及基本用法解析

news/2024/5/11 4:16:39/文章来源:https://blog.csdn.net/qq_27496129/article/details/137558469

1. 什么是Java Stream

  • 1.1 Stream概念介绍

Java Stream是Java 8中引入的一种处理集合的新方式,它可以让开发者以一种类似于SQL语句的声明方式来操作集合,提供了一种高效且便捷的数据处理方式。Stream使用函数式编程的思想,可以大大简化集合数据的处理过程,使代码更加简洁和易读。

  • 1.2 Stream和Collection的区别

Stream 和 Collection 是Java中处理集合数据的两种机制,它们之间有以下几点区别:
- Collection 是一种静态的内存数据结构,而 Stream 是有关计算的。
- Collection 提供了存储和访问数据的方式,而 Stream 本身不存储数据,它只是描述对数据的运算。
- Collection 是数据结构,Stream 是对这些数据的操作。
- Collection 是同步的,它会阻塞操作,而 Stream 是异步的,它可以并行执行。

2. 创建Stream

  • 2.1 从集合创建Stream

通过集合类的 stream() 方法,可以轻松地将集合转换为一个 Stream 来进行各种操作。

List<String> list = Arrays.asList("apple", "banana", "orange", "grape");
Stream<String> stream = list.stream();
  • 2.2 通过Stream静态工厂方法创建Stream

除了从集合创建Stream,我们还可以使用 Stream 的静态工厂方法来创建Stream,比如 Stream.of() 方法。

Stream<String> streamOf = Stream.of("apple", "banana", "orange", "grape");

通过上面两种方式,我们可以方便地创建一个 Stream 对象,为接下来的操作做准备。

总结

Java Stream 中,我们可以通过集合类的 stream() 方法或者 Stream 的静态工厂方法来创建 Stream 对象,以便进行后续的操作。这些方法提供了方便快捷地创建 Stream 的途径,使得数据处理更加高效。

简单的创建Stream流程示意图

graph LR
A[创建集合] --> B(集合.stream())
C[直接静态方法创建] --> D(Stream.of())
B --> E(获取Stream)
D --> E
E --> F[后续操作]

通过以上 Stream 创建的方式,我们可以在开始阶段就轻松获取到数据处理所需的 Stream 对象,为后续的操作打下良好的基础。

3. Stream中的中间操作

在Java Stream中,中间操作是对Stream进行一系列连续操作的过程,这些操作会返回一个新的Stream对象。这一章节将介绍Stream中的几种常用中间操作,并给出相应的示例代码和示意图。

  • 3.1 Filter(过滤)

Filter操作可以根据指定的条件过滤出Stream中符合条件的元素。

示例代码:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);List<Integer> filteredList = numbers.stream().filter(num -> num % 2 == 0).collect(Collectors.toList());System.out.println(filteredList);

结果说明:上述代码中,通过Filter操作筛选出了列表中的偶数元素,最终输出结果为[2, 4, 6, 8, 10]。

  • 3.2 Map(映射)

Map操作可以对Stream中的每个元素进行映射转换操作。

示例代码:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");List<Integer> nameLengths = names.stream().map(String::length).collect(Collectors.toList());System.out.println(nameLengths);

结果说明:上述代码利用Map操作将字符串列表中的每个元素转换为其长度,最终输出结果为[5, 3, 7]。

  • 3.3 Sorted(排序)

Sorted操作可以对Stream中的元素进行排序操作。

示例代码:

List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6, 5, 3);List<Integer> sortedList = numbers.stream().sorted().collect(Collectors.toList());System.out.println(sortedList);

结果说明:上述代码通过Sorted操作将列表中的元素进行升序排序,最终输出结果为[1, 1, 2, 3, 3, 4, 5, 5, 6, 9]。

  • 3.4 Limit(截取)

Limit操作可以对Stream进行截取操作,限制返回的元素个数。

示例代码:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);List<Integer> limitedList = numbers.stream().limit(5).collect(Collectors.toList());System.out.println(limitedList);

结果说明:上述代码通过Limit操作限制返回前5个元素,最终输出结果为[1, 2, 3, 4, 5]。

以上是Stream中的几种常用中间操作,它们可以灵活结合以实现对数据的多种处理和转换操作。通过这些中间操作,我们可以方便地对数据进行筛选、转换、排序和截取等处理。

4. Stream中的终端操作

在Java Stream中,终端操作是指当流经过所有的中间操作后,需要对流执行的最终操作。终端操作会触发流的遍历与处理,生成最终的结果。在本章中,我们将详细介绍几种常见的Stream终端操作及其用法。

4.1 forEach

在Stream中,forEach是一种常见的终端操作,用于对流中的每个元素执行指定的操作。例如,我们有一个整数列表,我们可以使用forEach来输出每个元素的平方值:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);numbers.stream().map(num -> num * num).forEach(System.out::println);

在上面的代码中,我们首先将列表中的每个元素进行平方操作,然后使用forEach输出每个元素的平方值。

4.2 collect

另一个常见的终端操作是collect,它将流中的元素收集起来并返回一个新的集合。我们可以使用collect来将流中的元素收集到一个列表中:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");List<String> filteredNames = names.stream().filter(name -> name.length() > 4).collect(Collectors.toList());// 输出筛选后的名字列表
filteredNames.forEach(System.out::println);

在上面的代码中,我们筛选出长度大于4的名字,并将它们收集到一个新的列表filteredNames中。

4.3 reduce

reduce操作可以将流中的所有元素归约成一个结果。例如,我们可以使用reduce来计算列表中所有元素的和:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);int sum = numbers.stream().reduce(0, (a, b) -> a + b);System.out.println("Sum of numbers: " + sum);

在上面的代码中,我们使用reduce对列表中的所有元素进行求和操作,初始值为0。

通过这些终端操作,我们可以对Stream进行处理并得到我们想要的结果,从而实现更加灵活和高效的数据处理操作。

开始
中间操作
中间操作
中间操作
终端操作
结果处理

以上就是Java Stream中的终端操作的介绍,通过合理使用这些终端操作,我们可以更好地利用Stream来处理数据,提高代码的可读性和易维护性。

5. Stream并行处理

在Java Stream中,通过并行处理可以充分利用多核系统的优势,提高处理大数据集合时的效率。本章将介绍如何创建并行Stream以及并行Stream与顺序Stream的比较。

5.1 并行Stream的创建

在Java中,可以通过parallel()方法将一个顺序Stream转换为并行Stream,示例如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);// 顺序Stream
Stream<Integer> sequentialStream = numbers.stream();// 并行Stream
Stream<Integer> parallelStream = numbers.parallelStream();

通过parallel()方法,我们可以轻松地将顺序Stream转换为并行Stream,从而利用多线程并发处理数据。

5.2 并行Stream与顺序Stream的比较

并行Stream与顺序Stream的主要区别在于数据处理的方式。在顺序Stream中,数据是按照插入顺序依次处理的,而在并行Stream中,数据会被分配到多个线程上并行处理,最后再将结果合并。

下表对比了并行Stream和顺序Stream的特点:

特点顺序Stream并行Stream
处理方式依次处理每个元素并行处理多个元素
运行效率适用于小规模数据集合适用于大规模数据集合,利用多核处理器提高效率
线程安全性线程安全需要注意线程安全性,可能需要同步操作
可控性相对简单易控制并行处理需要考虑线程安全、性能消耗等方面的因素

通过选择合适的Stream类型,可以根据实际场景提高数据处理效率。需要根据数据规模、数据处理复杂度等因素来选择使用顺序Stream还是并行Stream。

结论

并行Stream是Java中用于并行处理数据集合的重要工具,可以充分利用多核处理器的优势,提高数据处理效率。在实际开发中,根据数据规模和处理性能需求来选择合适的Stream类型,以达到最佳的数据处理效果。

6.1 数据筛选与转换

在实际开发中,经常需要对数据进行筛选和转换操作。通过Java Stream,我们可以轻松实现这些功能。下面我们来看一个简单的场景,筛选出集合中大于10的元素,并将它们转换成对应的平方值。

List<Integer> numbers = Arrays.asList(5, 12, 3, 18, 9, 7, 15);List<Integer> squaredNumbers = numbers.stream().filter(num -> num > 10).map(num -> num * num).collect(Collectors.toList());System.out.println("大于10的数对应的平方值: " + squaredNumbers);

通过上面的代码,我们首先筛选出集合中大于10的元素,然后将这些元素转换成对应的平方值,最后将结果收集到一个新的列表中并输出。这展示了如何通过Stream实现数据的筛选与转换。

6.2 数据聚合与统计

除了对数据进行筛选与转换外,Java Stream还提供了丰富的方法来实现数据的聚合与统计功能。下面我们来看一个实际场景,计算集合中所有元素的平均值。

List<Integer> scores = Arrays.asList(80, 90, 75, 95, 85);Double average = scores.stream().mapToDouble(Integer::doubleValue).average().orElse(0);System.out.println("平均分数为: " + average);

在上面的示例中,我们先将集合中的整数转换为double类型,然后调用average方法计算平均值,并使用orElse方法处理空集合的情况,最终输出平均分数。

6.3 数据分组与分区

除了基本的数据操作外,Java Stream还可以实现数据的分组和分区。下面我们来看一个场景,根据学生成绩将学生分为及格和不及格两组。

List<Student> students = Arrays.asList(new Student("Alice", 85),new Student("Bob", 60),new Student("Charlie", 75),new Student("David", 45),new Student("Eva", 90)
);Map<Boolean, List<Student>> passMap = students.stream().collect(Collectors.partitioningBy(s -> s.getScore() >= 60));System.out.println("及格学生: " + passMap.get(true));
System.out.println("不及格学生: " + passMap.get(false));

通过以上代码,我们利用partitioningBy方法根据学生成绩及格与否将学生分为两组,并最终输出结果。这展示了如何利用Stream实现数据的分组与分区功能。

通过以上示例,我们可以看到Java Stream在数据处理方面的强大之处。从数据筛选转换到数据统计聚合再到数据分组分区,Stream提供了丰富的方法满足各种数据处理需求。深入学习和灵活运用Stream,将会极大提升代码的简洁性和可读性。

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

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

相关文章

应急响应-挖矿脚本检测指南威胁情报样本定性文件清除入口修复

一、演示案例-挖矿样本-Win&Linux-危害&定性 危害&#xff1a;CPU拉满&#xff0c;网络阻塞&#xff0c;服务器卡顿等 定性&#xff1a;威胁情报平台上传解析分析&#xff0c;文件配置查看等windows样本 linux样本 二、演示案例-Linux-Web安全漏洞导致挖矿事件 某公司…

一例简单的文件夹病毒的分析

概述 这是一个典型的文件夹病毒&#xff0c;使用xp时代的文件夹图标&#xff0c;通过可移动存储介质传播&#xff0c;会向http://fionades.com/ABIUS/setup.exe下载恶意载荷执行。 其病毒母体只是一个加载器&#xff0c;会在内存是解密加载一个反射型的dll&#xff0c;主要的…

【C++】缺省参数和函数重载

目录 1.缺省参数 1.1缺省参数的定义 1.2 缺省参数的简单应用 1.3 缺省参数分类&#xff1a;全缺省参数和半缺省参数 1.3.1半缺省参数 1.3.2全缺省参数 3.缺省参数注意事项&#xff1a;缺省参数不能在函数声明和定义中同时出现 4.函数重载 4.1 函数重载概念 4.2 函数参数类型…

2024年32款数据分析工具分五大类总览

数据分析工具在现代商业和科学中扮演着不可或缺的角色&#xff0c;为组织和个人提供了深入洞察和明智决策的能力。这些工具不仅能够处理大规模的数据集&#xff0c;还能通过强大的分析和可视化功能揭示隐藏在数据背后的模式和趋势。数据分析工具软件主要可以划分为以下五个类别…

uniapp Android 开发手机模拟器调试接口出现 Failed to connect to localhost/127.0.0.1:9999

{“errMsg”:“request:fail abort statusCode:-1 Failed to connect to localhost/127.0.0.1:9999”} 原因&#xff1a;使用模拟器或者手机调用API接口&#xff0c;首先保证在同一局域网&#xff0c;然后要使用 IPV4 的 IP 地址。 打开 cmd 输入 ipconfig 查看 ip 地址 替换代…

【java】spring打包找不到主类

背景 使用IDEA打包spring 一直报错&#xff0c;&#xff1a;IDEA spring Error: Could not find or load main class 解决 添加maven的打包命令&#xff1a; 添加&#xff0c;打包依赖到 jar包中 package assembly:single

蓝桥杯练习系统(算法训练)ALGO-958 P0704回文数和质数

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 一个数如果从左往右读和从右往左读数字是完全相同的&#xff0c;则称这个数为回文数&#xff0c;比如898,1221,15651都是回文数。编写…

创新指南|贝恩的产品经理RAPID框架:解决问题的分步指南,使决策过程既高效又民主

您是否曾发现自己陷入项目的阵痛之中&#xff0c;决策混乱、角色不明确、团队成员之间的冲突不断升级&#xff1f;作为产品经理&#xff0c;驾驭这艘船穿过如此汹涌的水域可能是令人畏惧的。应对这些挑战的关键在于采用清晰、结构化的决策方法。输入贝恩的 RAPID 框架&#xff…

Linux文件搜索工具(gnome-search-tool)

opensuse下安装: sudo zypper install gnome-search-tool 操作界面:

【Spring】SpringBoot整合Redis,用Redis实现限流(附Redis解压包)

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 本文介绍SpringBoot整合Redis并且进行接口的限流&#xff0c;文章主要介绍的是一种思想&#xff0c;具体代码还要结合实际。 一、Windows安装Redis Redis的解压包我放在了百度网盘上&#xff0c;有需要的可以下载。 R…

【第七篇】使用BurpSuite进行主动、被动扫描和主动、被动爬虫

文章目录 前言主动扫描被动扫描主动爬虫被动爬虫前言 Burp Scanner 既可以用作全自动扫描仪,也可以用作增强手动测试工作流程的强大手段。 扫描网站涉及两个阶段: 抓取内容和功能: Burp Scanner 首先在目标站点周围导航,密切反映真实用户的行为。它对站点的结构和内容以及…

06 Php学习:字符串

PHP 中的字符串变量 在 PHP 中&#xff0c;字符串是一种常见的数据类型&#xff0c;用于存储文本数据。字符串变量可以包含字母、数字、符号等字符&#xff0c;并且可以进行各种操作和处理。以下是关于 PHP 中字符串变量的一些重要信息&#xff1a; 定义字符串变量&#xff1…

Spring boot 入门 ---(一),2024年最新java进阶训练营

spring-snapshots http://repo.spring.io/snapshot spring-milestones http://repo.spring.io/milestone spring-boot-starter-parent是使用Spring Boot的一种不错的方式&#xff0c;但它 并不总是最合适的。有时你可能需要继承一个不同的父POM&#xff0c;或只是不喜欢我…

JVM面试整理--对象的创建和堆

文章目录 对象的创建过程是怎样的?对象在内存中的结构是怎样的&#xff08;专业的叫法&#xff1a;对象的内存布局&#xff09;对象在内存分配时使用的哪种方式&#xff08;有的地方也称为&#xff1a;分配算法&#xff09;知道什么是“指针碰撞”吗&#xff1f;知道什么是“空…

不允许在constexpr函数中进行声明

这是我用pycharm在windows系统下复现sfm深度学习网络(Deep Two-View Structure-from-Motion Revisited&#xff09;遇见的问题&#xff0c;复现时有段代码pytorch扩展cuda/c&#xff0c;pycharm中出现C标准相关的报错如下&#xff1a; 在网上查找很久无果&#xff0c;后面通过…

JVM垃圾收集——垃圾收集器

文章目录 1、垃圾收集器的发展和分类1.1、评估垃圾收集器的性能指标1.1.1、吞吐量1.1.2、停顿时间1.1.3、吞吐量和停顿时间的比较 1.2、垃圾收集器的发展史1.3、垃圾收集器的分类1.4、查看默认的垃圾收集器 2、Serial收集器&#xff1a;串行回收3、ParNew收集器&#xff1a;并行…

【漏洞复现】深澜计费管理系统任意文件读取漏洞

0x01 产品简介 深澜计费管理系统是一套完善的、领先的具有复杂生物型特征的弹性认证计费系统。其主要由以下几个模块组成&#xff1a;AAA认证计费平台、系统运营维护管理平台、用户及策略管理平台、用户自助服务平台、智能客户端模块、消息推送模块以及数据统计模块。该系统为…

Qt Creator实例之图标主题

Chart themes 是 Qt Creator 中图表的主题&#xff0c;它可以用于改变图表的外观和风格&#xff0c;使其更符合你的需求和设计。此示例显示了所有支持的图表类型的不同内置主题的外观。为了给结果一个更和谐的外观&#xff0c;应用程序的背景调色板是根据所选主题定制的。 char…

Mybatis-Plus05(分页插件)

分页插件 MyBatis Plus自带分页插件&#xff0c;只要简单的配置即可实现分页功能 1. 添加配置类 Configuration MapperScan("com.atguigu.mybatisplus.mapper") //可以将主类中的注解移到此处 public class MybatisPlusConfig {Bean public MybatisPlusIntercepto…

功能测试如何到自动化测试,看这篇就够了。

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;薪资嘎嘎涨 本帖不仅给大家介绍自动化测试&#xff0c;更会提供大…