Java基础学习第二十四讲:Stream流

Stream流

一、什么是Stream流

Stream流操作是Java 8提供一个重要新特性,它允许开发人员以声明性方式处理集合,其核心类库主要改进了对集合类的 API和新增Stream操作。Stream类中每一个方法都对应集合上的一种操作。将真正的函数式编程引入到Java中,能 让代码更加简洁,极大地简化了集合的处理操作,提高了开发的效率和生产力。
同时stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。在Stream中的操作每一次都会产生新的流,内部不会像普通集合操作一样立刻获取值,而是 惰性取值 ,只有等到用户真正需要结果的时候才会执行。 并且对于现在调用的方法,本身都是一种高层次构件,与线程模型无关。因此在并行使用中,开发者们无需再去操 心线程和锁了。Stream内部都已经做好了 。
个人的理解:Stream流就好像一座城市的饮用水管线,我们的数据就好像流水一样,在进入我们的管道后,通过各种过滤、杀菌、物质筛查等工序,最终流入千家万户。我们的数据也是一样,最初是比较综合、庞大的数据源,通过我们Stream流的查找、过滤、组合、计算、操作、分组等过程,执行完毕之后获取到我们想要的结果。
在这里插入图片描述Stream流特征:

  • Stream流不存储数据
  • Stream流不改变数据源
  • Stream流不可重复执行

二、Stream流的分类

Stream流根据执行过程可分为:

  • 串行流:所谓串行流是指在Stream流执行过程中,在同一线程下逐一执行相应的操作,直到所有操作处理完成。

  • 并行流:所谓并行流是指在Stream流执行过程中,在多个线程中分别执行相应的操作,直到所有操作处理完成。
    在这里插入图片描述
    并行流在底层实现中,是沿用了Java7提供的fork/join分解合并框架进行实现。fork根据cpu核数进行数 据分块,join对各个fork进行合并。因并行流是通过多线程进行拆分额整合,所以需要保持线程安全,个人建议不要什么集合都通过Stream流进行操作。

    注意:不是串行流就一定比并行流效率低,更不是流处理就一定比for循环效率低,要根据实际情况慎重选择

三、Stream流常用操作

Stream流多数是对集合或数组进行操作,根据操作的过程,可分为中间操作和终端操作。

  • 创建流:在Java8中,Collection 接口被扩展,提供了两个获取流的默认方法。stream()方法返回一个串行流,parallelStream()方法返回一个并行流。
  • 中间操作:中间操作会返回一个流,可以通过这种方式将多个流或多个操作连接在一起,形成一个新的链条,从而获得新的流的结果,直到遇到一个终端操作,最终返回一个结果。中间操作又分为无状态操作(不受前一步操作的影响)和有状态操作(需要获取到所有元素后在进行操作)
  • 终端操作:终端操作就是通过流的处理最终得到一个结果。终端操作又分为短路操作(遇到符合条件的元素直接获得最终结果)和非短路操作(必须处理完所有元素才能得到最终结果)
操作类型方法名方法功能
中间操作filter参数是一个boolean类型的Lambda表达式,根据条件获取新的流
中间操作peek参数是方法,根据指定的方法对数据进行操作,并且不会改变原有数据,一般用于程序调试
中间操作map将Stream中的元素进行函数式变化,将新的元素保存到Stream中
中间操作mapToXxx将Stream中的元素转换成对应数值,将新的元素保存到Stream中,可以返回相应数据类型的数组
中间操作flatMap将内部的集合转换成为Stream流,再次进行相关操作,实现数据扁平化
中间操作flatMapToXxx将内部相关的集合转换成为Stream流,再次进行相关操作,实现数据扁平化
中间操作skip将参数的元素跳过再返回一个流,如果流中的元素小于或者等于参数个数,就会返回一个空的流
中间操作limit返回指定数量的元素的流。返回的是Stream里前面的参数个数元素
中间操作distinct去掉Stream流中的重复项
中间操作sorted对Stream流中的元素进行排序,元素是数据,无参为默认排序,元素是对象,可以通过比较器进行比较
终端操作forEach循环所有的元素
终端操作forEachOrdered循环所有的元素,如果Stream流是并行流,那么forEach不一定按照顺序执行,但forEachOrdered一定按顺序执行
终端操作toArray将Stream流转换为数组
终端操作collect将Stream流转换为集合
public class Main {
	public static void main(String[] args) {
		List<String> nikeNames=new ArrayList<String>();
		nikeNames.add("1");
		nikeNames.add("2");
		nikeNames.add("3");
		List<User> list=new ArrayList<User>();
		list.add(new User("张三", 20, "男",nikeNames));
		list.add(new User("李四", 32, "男",nikeNames));
		list.add(new User("王五", 12, "女",nikeNames));
		list.add(new User("赵六", 32, "男",nikeNames));
		list.add(new User("钱七", 34, "女",nikeNames));
		list.add(new User("孙八", 21, "男",nikeNames));
		list.add(new User("周九", 54, "女",nikeNames));
		list.add(new User("冯十", 23, "女",nikeNames));
		
		list.stream().filter(user->user.getAge()>18).collect(Collectors.toList()).forEach(System.out::println);
		list.stream().peek(user->System.out.println("会员信息"+user)).forEach(System.out::println);
		list.stream().map(User::getName).forEach(System.out::println);
		list.stream().flatMap(user->user.getNikeNames().stream()).collect(Collectors.toList()).forEach(System.out::println);
		list.stream().limit(2).collect(Collectors.toList()).forEach(System.out::println);
		list.stream().skip(2).collect(Collectors.toList()).forEach(System.out::println);
		list.stream().distinct().forEach(System.out::println);
		list.stream().sorted().forEach(System.out::println);
		list.stream().sorted((u1,u2)->u1.getAge()-u2.getAge()).forEach(System.out::println);
		
	}

}

class User{
	private String name;
	private int age;
	private String sex;
	private List<String> nikeNames;
	
	public User() {
	}
	public User(String name, int age, String sex, List<String> nikeNames) {
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.nikeNames = nikeNames;
	}
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public List<String> getNikeNames() {
		return nikeNames;
	}

	public void setNikeNames(List<String> nikeNames) {
		this.nikeNames = nikeNames;
	}

	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + ", sex=" + sex + "]";
	}
}

四、Stream的特点

  • Stream只能处理一次数据:Stream流的从一端获取数据源,在流中依次对元素进行操作,当元素通过流,便无法再对其进行操作,可以重新在数据源获取一个新的流进行操作
  • Stream流采用内部迭代方式:对集合进行处理,一般会使用迭代器的遍历方式,这是一种外部迭代;而对于处理Stream流,只要申明处理方式,处理过程由流对象自行完成,这是一种内部迭代,对于大量数据的迭代处理中,内部迭代比外部迭代要更加高效
  • Stream流为无存储: Stream流并不存储值;流的元素源自数据源(可能是某个集合、数组或I/O通道等等),通过一系列计算步骤得到
  • 函数式风格: 对Stream流的操作会产生一个结果,但流的数据源不会被修改
  • 惰性求值: 多数流操作都是以惰性方式实现,一遍遍历完成整个流水线操作,并可以用短路操作提供更高效的实现
  • 无需上界: Stream流可以被表达为无限流,用户不停地读取流直到满意的结果出现为止,集合是有限的,但流可以表达为无线流
  • 代码简练: 对于一些集合的迭代处理操作,使用Stream流编写可以十分简洁

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

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

相关文章

ROS功能包|mav_control_rw(基于MPC的无人机轨迹跟踪控制)---gazebo仿真测试

ROS功能包|mav_control_rw&#xff08;基于MPC的无人机轨迹跟踪控制&#xff09;---gazebo仿真测试gazebo仿真测试gazebo仿真测试 启动gazebo并加载无人机模型 $ roslaunch rotors_gazebo mav.launch mav_name:firefly启动 linear mpc 控制器 $ roslaunch mav_linear_mpc ma…

Win10安装MySql1.5.7

1&#xff09;、下载安装包 地址&#xff1a;MySQL :: Download MySQL Community Server 或者&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1iSLiUo8ehqP6tfxGJ2ewfA 提取码&#xff1a;ctbr 2&#xff09;、下载后解压到指定目录 我的是D:\Program Files\mysql-…

SCS【19】单细胞自动注释细胞类型 (Symphony)

单细胞生信分析教程桓峰基因公众号推出单细胞生信分析教程并配有视频在线教程&#xff0c;目前整理出来的相关教程目录如下&#xff1a;Topic 6. 克隆进化之 CanopyTopic 7. 克隆进化之 CardelinoTopic 8. 克隆进化之 RobustCloneSCS【1】今天开启单细胞之旅&#xff0c;述说单…

一图看懂 bz2 模块:处理压缩和解压缩文件, 资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 bz2 模块&#xff1a;处理压缩和解压缩文件, 资料整理笔记&#xff08;大全&#xff09;摘要模块图类关系图模块全展开【bz2】统计常量int模块4 io5 os6 warnings7 _compre…

数据结构与算法基础(王卓)(23):邻接表(链式存储结构)

顶点结点&#xff1a; //顶点的结点结构 typedef struct VNode {VertexType data; //顶点信息ArcNode* firstarc; //指向第一条依附该顶点的边的指针 }VNode, AdjList[MVNum]; //例如&#xff1a;VNode v[MVNum] 相当于 AdjList v 我觉得也可以改成这样写&#xff08;存疑&…

基于数字孪生智慧污水厂Web3D可视化管理系统

城市水环境不仅关系到国民生活的质量&#xff0c;还对我国社会发展有着深入的影响。城市污水处理厂的存在不仅能够提升生态环保工作发挥的效用&#xff0c;还能够向城市居民宣传生态环保的重要性&#xff0c;使得更多的市民认识到节约、环保的意义&#xff0c;能够从自身出发&a…

UVM学习笔记2——验证基础知识(验证计划、验证方法)

文章目录前言一、覆盖率二、验证计划1、验证计划模板2、验证计划评估三、验证方法1、动态仿真/dynamic simulation2、静态检查/formal check3、虚拟模型4、硬件加速/hardware acceleration5、效能验证6、性能验证四、验证分类1、验证工具2、验证复杂度/可见度/透明度3、验证的芯…

Java设计模式(一)单例模式

设计模式是对软件设计中普遍存在的各种问题&#xff0c;提出解决方案 设计模式包含了面向对象的精髓&#xff0c;懂了设计模式&#xff0c;你就懂了面向对象分析和设计的精要。 设计模式的七大原则 1.单一职责原则 2.接口隔离原则 3.依赖倒置原则 4.里氏替换原则 5.开闭原则o…

大数据项目实战之数据仓库:用户行为采集平台——第2章 项目需求及架构设计

第2章 项目需求及架构设计 2.1 项目需求分析 1&#xff09;采集平台 &#xff08;1&#xff09;用户行为数据采集平台搭建 &#xff08;2&#xff09;业务数据采集平台搭建 2&#xff09;离线需求 主题 子主题 指标 流量主题 各渠道流量统计 当日各渠道独立…

pdf压缩文件怎么压缩最小?办公常备软件

PDF文件的大小有时会让人感到困扰&#xff0c;特别是在网络上传输和存储方面。为了解决这个问题&#xff0c;我们需要将PDF文件压缩至最小。 在进行压缩之前&#xff0c;需要检查PDF文件的分辨率和图形质量。通过降低分辨率和图形质量&#xff0c;可以显著减小文件的大小。此外…

springCloud学习【6】之分布式搜索引擎(3)

文章目录前言一 数据聚合1.1 DSL实现聚合1.1.1 Bucket聚合语法1.1.2 聚合结果排序1.1.3 限定聚合范围1.2 Metric聚合语法1.3 小结1.4 RestAPI实现聚合1.5 API语法1.7 案例二 自动补全2.1 拼音分词器的安装2.2 自定义分词器2.3 自动补全查询2.4 自动补全查询的JavaAPI三 数据同步…

Unity升级后打包AssetBundle变慢

1&#xff09;Unity升级后打包AssetBundle变慢 ​2&#xff09;打包使有些资源合成了一个资源data.unity3d&#xff0c;有些分开的原因 3&#xff09;Unreal在移动设备中无法使用Stat命令获取到GPU Thread的耗时 4&#xff09;Unity中如何看到相机视野范围内的剔除结果 这是第3…

【C++】迭代器

内容来自《C Primer&#xff08;第5版&#xff09;》9.2.1 迭代器、9.2.3 begin和end成员、9.3.6 容器操作可能使迭代器失效、10.4.3 反向迭代器 目录 1. 迭代器 1.1 迭代器范围 1.2 使用左闭合范围蕴含的编程假定 2. begin和end成员 3. 容器操作可能使迭代器失效 3.1 编…

【SQL基础笔记】

本文标签: SQL语法 SQL分类 DDL DML DQL DCL 目录 一、SQL语法 二、SQL的分类 三、DDL 1.DDL-数据库操作 2.DDL-表操作 3.DDL-数据类型 4.DDL-表操作 四、DML 五、DQL 1.DQL-基本查询 2.DQL-条件查询: 3.DQL-聚合函数 4.DQL-分组查询 5.DQL-排序查询 6.DQL-分页查询 7.综合案…

让ChatGPT在中断回答的时候自动输入「请接上文继续」并发送

一、脚本内容 让ChatGPT在中断回答的时候自动输入「请接上文继续」并发送 // UserScript // name ChatGPT自动接上文继续 // namespace http://tampermonkey.net/ // version 1.3 // description 让ChatGPT在中断回答的时候自动输入「请接上文继续」并发送 /…

Elasticsearch:高级数据类型介绍

在我之前的文章 “Elasticsearch&#xff1a;一些有趣的数据类型”&#xff0c;我已经介绍了一下很有趣的数据类型。在今天的文章中&#xff0c;我再进一步介绍一下高级的数据类型&#xff0c;虽然这里的数据类型可能和之前的一些数据类型有所重复。即便如此&#xff0c;我希望…

MySQL数据同步ES的常用思路和方法

文章目录 1.同步双写2.异步双写3.定时任务4.数据订阅大家应该都在各种电商网站检索过商品,检索商品一般都是通过什么实现呢?搜索引擎Elasticsearch。 那么问题来了,商品上架,数据一般写入到MySQL的数据库中,那么用于检索的数据又是怎么同步到Elasticsearch的呢? 1.同步双…

认识Spring(下)

作者&#xff1a;~小明学编程 文章专栏&#xff1a;Spring框架 格言&#xff1a;热爱编程的&#xff0c;终将被编程所厚爱。 目录 Spring更加高效的读取和存储对象 存储bean对象 五大注解 关于五大类注解 对象的注入 属性注入 构造方法注入 Setter注入 三种注入方式的…

IPV6 资料收集

IPV6与IPV4区别 1、地址长度的区别&#xff1a;IPv4协议具有32位&#xff08;4字节&#xff09;地址长度&#xff1b;IPv6协议具有128位&#xff08;16字节&#xff09;地址长度。 2、地址的表示方法区别&#xff1a;IPv4地址是以小数表示的二进制数。 IPv6地址是以十六进制表…