Java8实战-总结15

news2024/11/24 13:29:25

Java8实战-总结15

  • 引入流
    • 流简介
    • 流与集合

引入流

流简介

要讨论流,先来谈谈集合,这是最容易上手的方式。Java 8中的集合支持一个新的stream方法,它会返回一个流(接口定义在java.util.stream.Stream里)。在后面会看到,还有很多其他的方法可以得到流,比如利用数值范围或从I/O资源生成流元素。

流到底是什么?简短的定义就是“从支持数据处理操作的源生成的元素序列”。下面会一步步剖析这个定义。

  • 元素序列——就像集合一样,流也提供了一个接口,可以访问特定元素类型的一组有序值。因为集合是数据结构,所以它的主要目的是以特定的时间/空间复杂度存储和访问元素(如ArrayListLinkedList)。但流的目的在于表达计算,比如前面见到的filtersortedmap集合讲的是数据,流讲的是计算。
  • 源——流会使用一个提供数据的源,如集合、数组或输入/输出资源。请注意,从有序集合生成流时会保留原有的顺序。由列表生成的流,其元素顺序与列表一致。
  • 数据处理操作——流的数据处理功能支持类似于数据库的操作,以及函数式编程语言中的常用操作,如filtermapreducefindmatchsort等。流操作可以顺序执行,也可并行执行。

此外,流操作有两个重要的特点。

  • 流水线——很多流操作本身会返回一个流,这样多个操作就可以链接起来,形成一个大的流水线。这让一些优化成为可能,如延迟和短路。流水线的操作可以看作对数据源进行数据库式查询。
  • 内部迭代——与使用迭代器显式迭代的集合不同,流的迭代操作是在背后进行的。

让我们来看一段能够体现所有这些概念的代码:

从menu获得流
import static java.util.stream.Collectors.toList;
List<String> threeHighcaloricDishNames = 
					 menu.stream() //从menu获得流(菜肴列表)建立操作流水线:
					.filter(d -> d.getCalories() > 300)//首先选出高热量的
					.map(Dish::getName)//获取菜名
					.limit(3)//只选择头三个
					.collect(toList());//将结果保存在另一个List中

System.out.println(threeHighcaloricDishNames);//结果是[pork, beef, chicken]

在本例中,先是对menu调用stream方法,由菜单得到一个流。数据源是菜肴列表(菜单),它给流提供一个元素序列。接下来,对流应用一系列数据处理操作:filtermaplimitcollect。除了collect之外,所有这些操作都会返回另一个流,这样它们就可以接成一条流水线,于是就可以看作对源的一个查询。最后,collect操作开始处理流水线,并返回结果(它和别的操作不一样,因为它返回的不是流,在这里是一个List)。在调用collect之前,没有任何结果产生,实际上根本就没有从menu里选择元素。可以这么理解:链中的方法调用都在排队等待,直到调用collect。下图显示了流操作的顺序:filtermaplimitcollect,每个操作简介如下:
在这里插入图片描述

  • filter——接受Lambda,从流中排除某些元素。在本例中,通过传递lambda d -> d.getCalories() > 300,选择出热量超过300卡路里的菜肴。
  • map——接受一个Lambda,将元素转换成其他形式或提取信息。在本例中,通过传递方法引用Dish::getName,相当于Lambdad -> d.getName(),提取了每道菜的菜名。
  • limit——截断流,使其元素不超过给定数量。
  • collect——将流转换为其他形式。在本例中,流被转换为一个列表。可以把collect看作能够接受各种方案作为参数,并将流中的元素累积成为一个汇总结果的操作。这里的toList()就是将流转换为列表的方案。
    这段代码,与逐项处理菜单列表的代码有很大不同。首先,使用了声明性的方式来处理菜单数据,即对这些数据需要做什么:“查找热量最高的三道菜的菜名。”并没有去实现筛选(filter)、提取(map)或截断(limit)功能,Streams库已经自带了。因此,Stream API在决定如何优化这条流水线时更为灵活。例如,筛选、提取和截断操作可以一次进行,并在找到这三道菜后立即停止。

在进一步介绍能对流做什么操作之前,先回过头来看看Collection API和新的StreamAPI的思想有何不同。

流与集合

Java现有的集合概念和新的流概念都提供了接口,来配合代表元素型有序值的数据接口。所谓有序,就是按顺序取用值,而不是随机取用的。这两者有什么区别:

  • 比如说存在DVD里的电影,这就是一个集合(也许是字节,也许是帧),因为它包含了整个数据结构。
  • 现在再来想想在互联网上通过视频流看同样的电影。现在这是一个流(字节流或帧流)。流媒体视频播放器只要提前下载用户观看位置的那几帧就可以了,这样不用等到流中大部分值计算出来,就可以显示流的开始部分了(想想观看直播足球赛)。特别要注意,视频播放器可能没有将整个流作为集合,保存所需要的内存缓冲区——而且要是非得等到最后一帧出现才能开始看,那等待的时间就太长了。出于实现的考虑,也可以让视频播放器把流的一部分缓存在集合里,但和概念上的差异不是一回事。

粗略地说,集合与流之间的差异就在于什么时候进行计算。集合是一个内存中的数据结构,它包含数据结构中目前所有的值——集合中的每个元素都得先算出来才能添加到集合中。(可以往集合里加东西或者删东西,但是不管什么时候,集合中的每个元素都是放在内存里的,元素都得先算出来才能成为集合的一部分。)

相比之下,流则是在概念上固定的数据结构(不能添加或删除元素),其元素则是按需计算的。这对编程有很大的好处。这个思想就是用户仅仅从流中提取需要的值,而这些值——在用户看不见的地方——只会按需生成。这是一种生产者-消费者的关系。从另一个角度来说,流就像是一个延迟创建的集合:只有在消费者要求的时候才会计算值。

与此相反,集合则是急切创建的(供应商驱动:先把仓库装满,再开始卖)。以质数为例,要是想创建一个包含所有质数的集合,那这个程序算起来就没完没了,因为总有新的质数要算,然后把它加到集合里面。当然这个集合是永远也创建不完的,消费者这辈子都见不着了。

另一个例子是用浏览器进行互联网搜索。假设你搜索的短语在Google或是网店里面有很多匹配项。你用不着等到所有结果和照片的集合下载完,而是得到一个流,里面有最好的10个或20个匹配项,还有一个按钮来查看下面10个或20个。当你作为消费者点击“下面10个”的时候,供应商就按需计算这些结果,然后再送回你的浏览器上显示。
在这里插入图片描述
用DVD对比在线流媒体的例子展示了流和集合之间的差异

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

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

相关文章

自从学了C++之后,小雅兰就有对象了!!!(类与对象)(中)——“C++”

各位CSDN的uu们好呀&#xff0c;好久没有更新小雅兰的C专栏啦&#xff0c;话不多说&#xff0c;让我们进入类和对象的世界吧&#xff01;&#xff01;&#xff01; 类的6个默认成员函数 构造函数 析构函数 拷贝构造函数 类的6个默认成员函数 如果一个类中什么成员都没有&am…

C 语言中,「.」与「->」有什么区别?

使用“.”的话&#xff0c;只需要声明一个结构体。格式是结构体类型名结构体名。然后通过结构体名加上“.”再加上域名&#xff0c;就可以引用结构体的域了。因为结构体的内存是自动分配的&#xff0c;就像使用int a;一样。而使用“->”的话&#xff0c;需要声明一个结构体的…

【三维编辑】Seal-3D:基于NeRF的交互式像素级编辑

文章目录 摘要一、引言二、方法2.1.基于nerf的编辑问题概述2.2.编辑指导生成2.3.即时预览的两阶段学生训练 三、实验总结 项目主页: https://windingwind.github.io/seal-3d/ 代码&#xff1a;https://github.com/windingwind/seal-3d/ 论文: https://arxiv.org/pdf/2307.15131…

vue3 动态导入src/page目录下的所有子文件,并自动注册所有页面组件

main.js添加一下代码&#xff1a; const importAll (modules) > {Object.keys(modules).forEach((key) > {const component key.replace(/src/, /).replace(.vue, );const componentName key.split(/).slice(-2, -1)[0] -page;app.component(componentName, modules…

Vue2-简介、模板语法、数据绑定、MVVM、数据代理、事件处理

&#x1f954;&#xff1a;成功之后就能光明正大地回望所有苦难 VUE-Day1 Vue简介1、Vue是什么&#xff1f;2、谁开发的&#xff1f; 发展历程&#xff1f;3、Vue的特点4、容器和实例、实例中的el和data总结 Vue模板语法插值语法指令语法 数据绑定1.单向数据绑定&#xff08;v-…

SpringBoot入职学习

一、前言 公司入职&#xff0c;第一个事是把公司项目运行起来。然后在经过几天的颠沛流离&#xff0c;遇到一个事情。在创建yml文件的时候&#xff0c;需要设置自己的配置文件。当然还是先跑起来项目&#xff0c;就使用别人的yml文件。但是&#xff0c;到springboot配置那里卡…

视频抠像软件有哪些?简单好用视频抠像软件分享

在视频后期制作中&#xff0c;抠像通常用于将视频中的某个元素从其背景中分离出来。这种处理技术可以用于各种用途&#xff0c;比如创建特效、添加背景&#xff0c;或者将视频元素组合到新场景中。在电影、电视剧和广告等专业的影视制作中&#xff0c;抠像是一个常见的技术步骤…

cesium学习记录04-坐标系

一、地理坐标系和投影坐标系的关系 地理坐标系 (Geographic Coordinate System, GCS) 定义&#xff1a;地理坐标系是一个基于三维地球表面的坐标系统。它使用经度和纬度来表示地点的位置。 特点&#xff1a; 使用经纬度来定义位置。 基于特定的地球参考椭球体。 适用于全球范…

2023河南萌新联赛第(五)场:郑州轻工业大学 --亚托莉 -我挚爱的时光-

题目描述 亚托莉&#xff0c;-我挚爱的时光- 亚托莉自身机器可能有出了一点小故障&#xff0c;希望你能帮助她解决这个问题&#xff5e; 亚托莉内部的操作系统的是 Linux 操作系统&#xff0c;不同于 Windows 操作系统。在大多数情况下&#xff0c; Linux 操作系统一般是通过…

死磕Android性能优化,卡顿原因与优化方案

随着移动互联网的快速发展&#xff0c;Android应用的性能优化变得尤为重要。卡顿是用户体验中最常见的问题之一&#xff0c;它会导致应用的响应变慢、界面不流畅&#xff0c;甚至影响用户的使用体验。因此&#xff0c;我们需要深入了解卡顿问题的原因&#xff0c;并寻找相应的解…

(Python)Requests+Pytest+Allure接口自动化测试框架从0到1搭建

前言&#xff1a;本文主要介绍在企业使用Python搭建接口自动化测试框架&#xff0c;数据驱动读取excel表里的数据&#xff0c;和数据库方面的交互&#xff0c;包括关系型数据库Mysql和非关系型数据库MongDB&#xff0c;连接数据库&#xff0c;读取数据库中数据&#xff0c;最后…

刷题DAY18

题目一 LRU算法的实现 做一个key-value结构 假如说这个LRU的大小为3 那么就是当KEY-value没满的时候 直接顺序加入 当满了的时候 把最长时间没有使用的key-value替换掉 要求实现一个put 和 get行为 时间复杂度均为O(1) 用双向链表哈希表实现 哈希表可以用系统封装的双向链表…

node笔记——调用免费qq的smtp发送html格式邮箱

文章目录 ⭐前言⭐smtp授权码获取⭐nodemailer⭐postman验证接口⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于node调用免费qq的smtp发送邮箱。 node系列往期文章 node_windows环境变量配置 node_npm发布包 linux_配置node node_nvm安装配置 node笔记_h…

嵌入式开发的学习与未来展望:借助STM32 HAL库开创创新之路

引言&#xff1a; 嵌入式开发作为计算机科学领域的重要分支&#xff0c;为我们的日常生活和产业发展提供了无限的可能。STMicroelectronics的STM32系列芯片以其出色的性能和广泛的应用领域而备受关注。而STM32 HAL库作为嵌入式开发的高级库&#xff0c;为学习者提供了更高效、更…

Jmeter(六) - 从入门到精通 - 建立数据库测试计划(详解教程)

1.简介 在实际工作中&#xff0c;我们经常会听到数据库的性能和稳定性等等&#xff0c;这些有时候也需要测试工程师去评估和测试&#xff0c;因此这篇文章主要介绍了jmeter连接和创建数据库测试计划的过程,在文中通过示例和代码非常详细地介绍给大家&#xff0c;希望对各位小伙…

浅谈JVM中的即时编译器(Just-In-Time compiler, JIT)

Java虚拟机&#xff08;JVM&#xff09;中的即时编译器&#xff08;Just-In-Time compiler, JIT&#xff09;是一个非常重要的组件&#xff0c;它负责将字节码转换为本地机器代码。在不使用JIT的情况下&#xff0c;JVM通过解释字节码来执行程序&#xff0c;这意味着它会为每个字…

24届近5年上海理工大学自动化考研院校分析

今天学姐给大家带来的是上海理工大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、上海理工大学 学校简介 上海理工大学&#xff08;University of Shanghai for Science and Technology&#xff09;是一所以工学为主&#xff0c;工学、理学、经济学、管理学、文…

如何实现Excel中多级数据联动

摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 在类Excel表格应用中&#xff0c;常用的需求场景是根据单元格之间的数据联动&…

Leetcode-每日一题【剑指 Offer 13. 机器人的运动范围】

题目 地上有一个m行n列的方格&#xff0c;从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动&#xff0c;它每次可以向左、右、上、下移动一格&#xff08;不能移动到方格外&#xff09;&#xff0c;也不能进入行坐标和列坐标的数位之和大于k的格子。例…

css3背景渐变

1.线性渐变 <style>.box {width: 200px;height: 200px;border: 1px solid black;float: left;margin-left: 50px;}.box1 {background-image: linear-gradient(green, yellow, red);}/* 右上 */.box2 {background-image: linear-gradient(to right top, green, yellow, re…