00:00
好,那么关于GD8的,我们说两大主要的新特性啊,一个呢叫拉曼表示,第二呢叫做PI,那么接着话呢,咱们就来讲一讲这个PI它的一个使用。好,那这块呢,关于我们这个stringpi呢,有一个介绍哈,说呢springpi它是真正的把真正的这个函数式编程的风格引入到我们这个Java当中,诶说呢是到目前为止对Java类库最好的补充,你看这个呢,给的这个地位还是比较高的啊,前面的话我们提到了叫真正的函数式编程,那因为呢,我们在中PI啊,相应的这个参数的位置啊,我们都提到了叫函数式接口啊,那我们再去啊提供这个函数式接口的实现类的对象的时候呢,咱们就可以使用相关的拉曼的表达式了,诶所以呢,就很好的体现了咱们函数式编程的一种风格。哎,它呢可以提高咱们Java程序的生产力,写出呢更高效干净和简洁的代码,那目前大家看可能没什么感觉,真正我们开始写的时候呢,你才有感觉。好,这里边儿有一句话啊,说呢我们,诶stringpi跟这个集合是什么关系。
01:02
说呢使用string API对集合中的数据啊进行操作,就类似于使用circle呢执行的数据库查询,诶这里边呢就提到了这个集合和PI啊,下边这块呢,其实也有介绍哈,说这个集合它呢是一种静态的内存的数据结构,讲的呢是数据。或者换句话说呢,我们这个集合啊,关注的是数据的存储,它呢是跟内存呢来打交道的,而我们这个PI呢,它是针对于集合的数据啊进行的操作,或者叫进行的运算啊,计算也可以,它呢是面向CPU的啊,这呢是一个主要的不同,那就类似于呢,咱们后面呢,大家还要学习的一个技术叫做circle。啊,稍微呢,接触过或者听说过数据库的同学呢,应该都知道啊,咱们针对于这个数据库中的这个表的数据啊,咱们可以呢去写叫增删改查的操作,对吧?那尤其呢,针对这个查询操作的话呢,我们说是最重要的,也是最复杂的,我们可以做很多种这个操作,比如过滤啊,Group分组是吧?诶相应的limit分页啊,哎等等这样一系列的一个操作,包括排序。
02:07
哎,那SQ呢,操作数据库那中的这个表,就类似于我们使用此中PI来操作集合当中的数据。这呢有这样的一个对应关系啊啊,那这呢,首先抛出个问题,说我们为什么还需要讲那个存储PI呢?诶刚才不是提到了说我们后期呢,可以使用circleq来操作数据库的查询吗?对吧?诶这里边儿就提到个问题,在实际开发当中,我们项目中的这个多数的数据源都来自于MYSQL和Oracle这样的叫关系型的数据库,那针对于关系型数据库呢,我们可以写相关的这个搜后语句,进行这个查询操作。对吧,诶当然我们现在这个数据呢,还有像这个DB等一些叫性的数据,那针对这样的数据相关的一些数据,我们就需要Java层面啊,做一些相关的处理了。啊,不知道大家这块呢,能不能看得懂哈,什么意思呢?简单来稍微的提一下,咱们后期的话呢,会讲这个数据库对吧,那数据库当中啊,咱们都有相关的一些表了啊,稍微的打开一张表,那针对于这个表中的数据啊,咱们就可以呢,使用这个SQL语句做相关的这种查询操作了,你比如说我想查看一下当前这个表中有多少条记录啊是吧?诶查询这个表中最大的这个,比如说生日是多少啊是吧?这个表当中包含比如说这个叫陈的。
03:22
啊,或者叫姓陈的啊,这个员工的啊,都有哪些呢等等,我们可以做非常丰富的这个S扣的这种查询。诶,那就意味着呢,比如说我们,诶通过用户的这个叫客户端是吧,或者我们叫浏览器啊,诶用户呢,发送了一个请求,说我就想查询这个表当中,诶这个姓陈的是吧,都有哪些员工,那这时候你发送的这个请求过来之后呢,到我们Java的后台,Java的后台这块呢,我们其实就可以写相应的这个SQL语句,然后发送到我们这个数据库这个层面。啊,这是我们这个data base是吧,诶这块我们做相关的这种查询,然后把这个结果呢,就返回到我们的Java后台,然后后台这块把数据呢再显给我们客户端显示就可以了,但其实我们这个测口在写的时候呢,查询数据库的时候呢,就可以把这个需求说,我只想查询包含陈的或者叫姓陈的这个员工都有哪些,那这块呢,我们已经做了一个过滤了,到我们Java层面这块已经是过滤以后的数据了,诶你只需要呢反馈客户端就可以了。
04:19
呃,也就是说呢,我们刚才这样的一个过滤的需求啊,你可以写在里面,但是的话呢,我们说针对于叫诶非关性的这个数据库啊,非RDBMS是吧。啊,这个叫数据库管理系统啊,R呢就是关系型数据管理系统,对于非关系型数据管理系统,比如说咱们说的red啊,芒DB啊,诶针对这样的数据库呢,我们就不在层面呢做这样的过滤了,咱们可以呢,查询到以后呢,在咱们这个内存层面,咱们使用stream API来实现这样的过滤行为。啊,这儿呢,就是我们说到的一种应用的场景。啊,这个大家注意一下这样一个情况啊好,下边呢,针对我们这个API呢,相关有一些说明,这个说明的话呢,咱们诶讲到具体的使用的时候呢,诶来给大家去做说明啊,首先回过来针对存储拍拍的一个使用,简单的我们写两个笔记啊第一个。
05:10
这上就提到了,说这个PI和我们集合框架的一个对比啊,大家呢,需要去清楚的啊,怎么着呢,咱们说呢,这个stream API是吧,它呢关注的是数据算。他呢,我们说关注。啊,关注的这个是啊,叫多个数据的这个计算,在这里边的计算都有哪些呢?比如说我们想排序啊,哎,想这个具体的查找啊,想这个做这个过滤的行为啊,包括这个映射的行为,包括便利的行为等啊这儿呢,都属于我们做相关的这种计算,它呢是面向。啊,咱们说这叫ACPU的。是吧,哎,那么对应的呢,咱们说的这个叫集合是吧。集合呢,咱们前面已经讲过了,它呢是一个容器,它关注的是。
06:01
哎,数据的一个存储是吧。哎,是面向。诶,咱们说那叫内存的。啊OK,注意啊,他然后刚才我们不是也提到了一个概念啊,说这个咱们,诶说这个诶叫stream API呢,诶。啊,至于这个集合啊,就类似于咱们的a circle呢,诶之于。呃,数据表的这个查询。诶这样的这个行为啊,OK行这块呢,我们也提到说为什么咱们要讲,诶咱们具体的这叫API了啊,就相当于呢,咱们针对于非关系型数据库中的这个数据的这个查询操作呢,我们就需要呢,使用诶Java代码层面的存API来实现。好,那么具体的使用呢,刚才我们提到了,这不是有这样四个点吗?CTRLC,暂且呢,咱们先把它粘过来。啊,然后呢,咱们在讲解下边这个使用的时候呢,就要提到这里边儿这个事儿了。
07:00
诶像这个第一个呢,我们还能够去理解一下,说这个stream呢,它自己不会存储数据,对,因为这个数据呢,还是使用这个集合来进行存储的,我们STEM的话呢,是针对于集合中的数据啊,可以做相关的计算。OK啊,这是第一个事儿,第二呢,说他不会改变数据返新的stream这块呢,咱们通过操作啊,大家才知道,那么具体的关于stringpi我们该如何去使用呢?这骤啊,整个呢,关于stream是个第一个骤呢,就涉及了stream。啊,说直白了就是造对象呗,啊这第一个事啊,然后第二的话呢,什么呢,我们叫哎stream,它一系列的。啊,一系列的啊,这叫中间操作。这个中间操作呢,说白了就是相关的这种方法的调用了,这块我写的叫一系列,也就是说呢,我们可以调用多个中中间操作啊OK,然后最后的话呢,我们第三步呢,就是执行这叫诶终止操作。诶注意这个终止操作呢,咱们只执行一次哈,而且呢,一旦执行了以后呢,你就不能再去执行其他的操作了,因为已经终止了嘛,是吧?诶这就我们说的这样一个情况啊好,这个呢,我们说叫面向是吧。
08:13
诶内存的啊,好,那么这儿呢,我们就把这几个步骤呢,就说清楚了,那首先呢,咱们来说第一个步骤叫stream的一个实例化,嗯,好,那么首先过来我们这儿呢,就写了几个这样的,呃,实体化的这个相关的一个说明,呃主要来讲呢,我们实体化的方式呢,有三种,第一种呢叫通过集合,第二种呢叫通过数组,第三种呢,叫通过stream的一个方法啊OK,静态方法。好,那么首先呢,我们看第一种啊,说通过集合我们可以获取一个STEM的一个实例,那集合的话呢,比如说诶,咱们在前面讲这个方案应用的时候呢,这不有个data嘛,在它里边啊,有一个叫employee data这样一个数组,在这样一个类,这个类里面呢,提供了一个方法,这个方法呢,能够返回一个list构成的一个。集合了,那我们就调一下这个静态方法就可以了,好所以呢,我们回过来啊,首先呢,可以这样做啊,找到咱们这个叫employee data是吧?诶通过这里边呢,我们一个叫get employees。
09:09
首先呢,通过这个方法,我们先得到一个list。这没问没问题了是吧。好,那么有了这个list以后啊,这个list的话呢,它有一个方法呢,就叫做这个诶stream这样的一个方法,那咱们直接呢,调用这个stream方法,此时呢,就能够返回一个诶stream这样的一个实例了。OK啊,这儿呢,我们说返回一个叫顺序流,什么意思啊,就是我们这儿呢,你看是一个例子,是一个有序的,这个里边呢,不是有相关的元素嘛,呃,添加的这个顺序呢,不就是1234以此类推是吧?那我们这里呢,返回的这个stream在操作数据的时候呢,就是按照里边这个元素这个顺序呢进行操作的。比如我们想判断一下,说,诶这里边儿呢,说谁的工资大于5000,那就是一个一个的往上去判断,这叫顺序流。OK,然后呢,我们还可以呢,获取一个并行流啊,实现呢,我们对数据操作的时候呢,效率的一个提升啊,如果我们集合中的数据比较多啊,这块你还可以呢,去调用我们这样一个方法叫parallel。
10:06
啊,比如我们拿着这侧点直接呢,我们就掉了一个parallel swim这呢就获取这个叫并行流。哎,这个加四等于一啊。啊行,这两个对象的话呢,其实暂且我们都没啥用啊。就我意思呢,指的就是说我们打印一下的话呢,其实没啥用。啊,因为呢,我们下边呢,要执行一系列的中间操作来体现它的一个应用,这块呢,只是打了一个地址而已,是吧?诶大家不用细看了啊好,这呢是我们说的第一种方式,也是我们使用比较多的一种方式,通过集合调方法就可以了。前面的话呢,我们没有讲过这个string方法是吧?诶这个方法的话,你看是在我们这个collection当中定义的是一个default的一个方法,咱不是说在G8当中接口当中是不是可以提供这种叫默认方法了。这意思吧,咱们前面呢,讲的时候呢,说了有15个方法,咱们当时讲这15个方法的时候呢,说都是什么呀,叫抽象方法。诶,关于这个接口里边呢,提供的这些默认方法,包括静态方法,咱没有具体去说啊,这块呢,我们来提一下这样的一个问题啊。
11:05
好,这呢是我们的第一种方式,第二种方式呢,这块提到说通过数组,哎,我们呢也可以获取啊,主要呢是调用a race。数组的这个工具类,它呢有个方法就叫做stream,你把这个数组呢,往里边一扔,我们就能够返回一个stream的一个实例了。啊,比较简单是吧,好,你比如说啊,我们这块呢,来一个叫类型的一个数组啊,叫A啊,你有一个型的数组。好,这里边儿呢,我就写个12345。呃,其实呢,会出现一个自动的装箱是吧,这个大家都清楚啊好,那么接着的话呢,我们通过这个点,咱们调这个叫stream这样的方法,然后呢,我们就把这个AR呢往里边一扔,然后呢,Al加个回车,诶这时候呢,咱们就得到了一个stream的一个实例了。好,那这个stream的话呢,里边就可以来操作我们的12345,注意啊,我们并没有说把12345又重新的存储在我们的stream当中了,刚才提到了说STEM呢,它本身是不存数据的,数据呢仍然是在我们这样一个数组当中啊,这个大家注意一下。
12:06
好,那么这块呢,我们生成的这个stream的话呢,里边操作的是类型的这个对象了,所以这块通过泛型我们能够非常清晰的看到它内部操作这个数据的这个类型是什么。啊,OK,行,那如果我们创建是一个基本数据类型的啊,你比如我这块写一个int类型的是吧。诶,这样一个数组,这儿呢,我也写成了12345。这个呢,就不用自动装箱了啊,然后呢,我们使用这个瑞点调这个命方法的时候呢,它呢也可以去传一个你看int型的数组。哎,它返回的是一个特殊的stream,叫t stream,你要传浪型的呢,就是long stream double呢就是double stream。啊也比较好理解,行,我们把这个are呢往这一扔,诶,然后这块返回的就是一个这样的一个结构。没问题是吧,OK啊这呢就指明了他呢是具体的来操作int类型的这个数据的。因为呢,我们那个STEM这块呢,你不能写int类型嘛。
13:00
对吧啊,因为咱们这个发型呢,只能够使用类是吧,这样类型呢进行充当啊,不能写基本水类型好,这样的话呢,我们得到这个四六或者461下边的话呢,你再去呃做这个中间操作就行了啊,咱们暂且呢就先放到这儿啊。这呢是咱们说的这个第二种场景,然后第三种场景,呃,因为呢,咱们说STEM呢,它主要是来操作多个数据的,我们这个数据呢,以容器的方式来去呈现啊,你可以是数组,也可以是集合,这是两种最常见的场景,那如果万一此时这个有多个数据,但多个数据呢,没有呈见为一个容器怎么办呢?我们还可以调STEM的一个静态方法啊,这就提到OF5的方法啊好,Stream点,哎,我们调这OF5的方式的时候,哎内部的话呢,我们可以填写多个变量。看这呢,你看就体现了是我们叫什么呀,哎,可边行参为代表的就是多个实例呗。啊,你比如说我们这个AA是吧。BB。啊CC是吧,再来一个这个嫂嫂是吧。啊,这个EDDD是吧,OK,这呢,我们就写了几个字串了,那写完以后的话呢,我们呃,就可以outt加一个回车啊,生成一个变量啊这个呢,我们仍然是叫stream。
14:11
啊,这块呢,也能够判断出来,我们当前的这个实例呢,都是string类型的,所以这块呢,就是一个死锥型的一个泛型,诶我就得到这个stream了。好得到它以后啊,咱们就可以做一系列的这个中间操作了。OK啊行,这呢是我们讲的三种方式,呃,重点呢,大家关注一下第一种啊第二种。没问题是吧,好,然后呢,这个我们说的,呃,第一步操作呢,结束以后,重点的话呢,我们是啊知道这个stream呢,他想操作的多个数据是谁了。那下一步的话呢,就是看你到底想做什么,这就是咱们所谓的一系列的叫中间操作啊,我在这儿呢,也画了一个具体的图啊,比如说针对于我们这个集合或者这个数组,首先呢,我们生命的一个,呃,创建了一个叫stream的一个实例了,接下来我们可以做filter,就叫过滤,Map叫映射啊等等一系列的叫中间操作。
15:03
最后的话呢,我们要有一个终止操作。啊,这就整个这样一个过程啊好,那么中间操作呢,都有哪些具体的行为呢?呃,这块呢,你看我列举出来了几波啊,第一步呢,叫筛选与切片啊对应的一些操作行为。呃,第二步呢,叫做映射行为。啊映射啊,就跟咱们高中讲的这个映射呢,是一个概念啊好,然后呢,下边呢,比如说排序的行为啊,主要呢,我们就列举出来的这样的三波。OK,好,那么针对于我们这里边儿这个中间操作啊,下边咱们做一个讲解啊。刚才呢,这不也提到了,说有这个叫筛选与切片,呃,有映射是吧,还有我们下边这叫排序啊,这样的这个三波这个操作。好,那首先的话呢,咱们来看这个第一波叫筛选与切片啊。嗯,来看我们这里边儿相关的这个需求了。好比如说我们第一个啊说呢,我们想查询员工表当中说薪资啊,大于7000的员工的信息。
16:02
哎,针对的就是咱们这个零二里边这个data中的这个数据了,所以呢,咱们需要先把这个呃集合是不是先拿到啊,这呢叫employee data啊,点employees啊,先获取我们当前这个员工构成的这个list了。好,拿着这个例子啊,注意看啊,接下来啊,首先呢,你需要获取一个STEM的一个实例了,咱们是刚才讲过这个调STEM这个方法,这呢不就拿到这个实例了吗。没问题吧,好拿这例以后呢,呃,比如我把这呢,先返回一个叫STEM显示的,把这个名字写出来啊好拿着这个STEM的话呢,下面要干什么事呢?呃,需要呢做一个过滤。我呢想查询这个表当中啊,说薪资大于7000的,诶你看我们这个表中的员工的这个薪资啊,有的呢是低于7000,有的是高于7000,我只要高于7000的员工的信息啊,那么怎么做呢?啊,那这块首先啊零点咱们这呢,调的这个操作呢,叫做filter。
17:00
Filter就是过滤的意思了,这个内部呢,需要填写一个啊,CTRLP一下叫predictdicate啊,这叫断言型或者叫断定型的一个接口了,这呢显然是一个函数式接口了。好了,出现函数接口了,我们需要提供一个它的接口的实现类的一个对象了,这样呢,我们是不是就可以使用拉姆达表达式啊?哎,只要你看到函数接口,一定可以使用它表示,至于说呢,能不能用方法引用,那就看缘分了。啊,那就看你里边具体一个操作的行为了啊,好,至少目前的话呢,我们写成一个拉表达式是没问题的,但是你看哈,我们此时呢,传进去的这个叫predictate呢,诶你看这个叫。哎,通服super employee。啊,这个呢,咱们不是前面讲过这样个就限制条件的一个通配服的使用是吧,其实这块你也不用过多的去关注我们这个通配服啊,咱们现在操作其实就是employee啊,所以这块我们就是一个employee啊,怎么着呢,我们想get一下它这个salary啊,判断是不是大于这个叫7000。咱们这个predictdic哎,它的是一个断定型的返回里边那个出方法的返回类型不是波尔类型吗?这不有尔类型吗。
18:04
哎,这就完事了是吧,好,那这样呢,我们就做了一个过滤的行为,那过滤完以后,你说我也不知道你这个到底靠不靠谱啊,过滤完以后这真正有啥效果呀。哎,目前来看啊,你是看不到任何的效果的。啊,这个呢,我们其实要提一个操作啊,诶这个操作叫什么呀,回过来啊,找到咱们一开始提到这个stream这个位置啊在这块啊这块的话呢,我们说有一系列的中间操作,注意这个中间操作呢,我们刚才呢,调了一个叫filter。其实这个filter我们调完以后的话呢,你会发现呢,它其实啊,好像你也看不到效果,因为我们也没有去做一个输出的行为是吧,那一旦要涉及到这个输出行为了,实际上呢,这就算是一个叫终止操作了。啊,这这其实就我们讲的终止操作中的一个了,呃,再者说如果我们这个stream呢,光写中间操作,不写这个终止操作的话呢,那这块这个中间操作呢,我们说呢,也不会去执行。
19:01
啊,这块相当于是有一个要求了是吧,这个要求呢,我们其实也可以把它称为呢,叫惰性求职。什么意思啊,就是我们这儿呢,得到一个stream了,接下来呢,你有一系列的一个中间操作,哎,最后呢,得有一个终止操作,如果没有终止操作,中间操作也不执行。就好比是呢,你这块呢,找一个工厂给你代工是吧,你说我要生产这个,比如衬衣啊,你帮我呢把它做出来,诶我给你付钱是吧,然后工厂这块说行没问题啊,我这样来设计啊,先设计一下,然后呢,我们再给你,呃,怎么着打版啊,怎么怎么有一系列的这个过程是吧,然后最后的话呢,这个衣服呢就造好了。诶然后付钱,诶这块呢,说你得先把这个钱呢,你先拍到这儿,拍到这儿之后我开始给你生产,你要不的话呢,中间诶刚才呢,提的这样的过程我都不给你做。诶,你可以这样的去理解这个事儿啊,啊这呢就是对应的回过来咱们这里边写的这样的一个声明说呢,就是stream这个操作,它是延迟执行的,这就意味着他们会等到需要结果的时候呢才执行,呃一旦执行终止操作,我们就执行一系列的一个中间操作。
20:05
啊,然后并产生一个结果。啊,就是注意一下这个意思,这呢就是我们啊,因为咱们现在写这个中间操作,你看不出效果了,所以咱们需要引入一个终止操作啊,叫做for each for each呢就是一个便利的意思。啊,这个呢,CTRLP一下里边呢,需要写一个叫consumer啊consumer一看是不是又是一个函数式接口了。啊,那里边我想干什么呢?诶,我就想把这个employee呢给他打印一下了,诶其实你发现呢,我们要调的是叫line print line的话呢,跟我们这里边的consumer这个,呃对应的这个抽象方法啊,它呢就是一个呃形成这个匹配关系了,呃说的直白一点哈,我现在就想用这个方法引用了。啊,就他,哎这个应该看不太懂是吧,你看咱们讲这个方法引用的时候,一开始我举的这个例子。我一开始举的例子不就是consumer吗?呃,然后这块,呃,咱不是写了一个这样一个结构吗。这呢我需要一个consumer的实例了,我们里边呢,就是system.out冒号,冒号就是做一个打印,咱们现在呢,其实用的就是这样个操作。
21:07
诶回过来,诶就是这个事儿。诶跟咱们刚才呢,说的这个例子啊,这块你看是完全匹配的啊好,我就呢,相当于把这里边儿的每一个employee呢,给你打印了一下,诶这个时候我们再去run一下就有效果了。你看,那我们只有呢这样的三个员工,他们的salary呢是大于7000的。稍微的体会一下啊,这呢就是咱们说对应的第一个需求,这呢是一个拉姆式,这呢是一个方法引用。OK啊。诶,这个呢,就是我们说的这个叫终止操作,然后接下来这个叫limit,它呢叫阶段流使其元素呢不超过给定的数量,说白了就是取我们当前这里边指定这个个数个元素啊,诶此时呢,大家要小心一点,你看我上面呢,是不是已经声明一个,诶声明得到了一个stream的实例了,我还能拿着这个stream再继续呢,去调这个limit这个操作。啊,写一下吗?比如我写个二是吧,哎,这个时候呢,我们这是个中间操作,要想能看效果,你是不是还得再去写个叫for each啊,哎,那里边的写法呢,一样,我就害怕他那粘过来了。
22:09
说呢,我想看一下当前STEM当中啊,前两个元素是谁来我们去做一个。大家注意看,这时候呢,我们报错了,叫非法的state,说呢呢已经操作完了,或者说呢,已经关闭了。这个就是我们要强调的啊,说一旦呢,这个STEM呢,你执行了这个终止操作了,你就不能再去调用了。啊,回过来是不是对应我们笔记当中啊,一旦执行了终止操作,就不能够再执行其他的中间操作或者叫终止操作了。诶,所以这块儿呢,要想能够去调这个limit这个操作怎么办呀,你是不是重新的再去调一下我们这个例子里边的这个STEM这个方法才行啊,相当于我们得生成一个新的STEM这个实例啊,你才能够再去调啊,这块大家一定要小心。我把刚才这个笔记呢给他留到这儿。
23:00
啊,这呢,我在这儿说明一下啊,这是一个啊,错误的说,因为呢,我们这个stream。啊,这个已经执行了,这个终止操作。就不可以啊在。呃,调用啊,其他的这个中间操作。或这个终止操作了。啊,这个大家一定要注意啊,那怎么办呢?就我们刚才提到你必须得新造一个是吧,通过绿色点我们调这个。诶,Stream这个方法得到一个新的stream,我们再去调这个limit,这呢,比如我写个四来写一个叫for each是吧。好,这里边儿呢,我们再去做一个便利啊好。诶print,那哎这就行了,好,那此时的话我们做一个run的操作啊。诶这块呢,就是我们打印的这样一个效果了,它是什么意思呢?诶我们针对这个集合中的这个数据。这个集合中的数据的话,这不就是零一啊,一直到这个零八,这不有八条数据嘛,我们现在呢,取的是它的前四条的这个数据,所以我们打印的这个效果呢,就是这个样子的。
24:01
是不是从011直到零四,这叫前四个。这块你写几,它就是前几个意思啊,两二啊,这块就是前两个。嗯,这不就这样个意思吗?没问题,那如果有同学会这样说啊,说呢,我想这个先过滤一下员工表中那个员工的薪资大于7000的,大于7000当中我取前两个。那怎么办啊,那其实很好办,那你只需要呢,先做一个是不是过滤的一个行为,过滤完以后呢,你再做一个不就可以了吗。哎,这不就行了吗?是吧,也就是说呢,咱们中间这个操作啊,这是一个,这是第二个,这是一系列的,你可以呢,连续的去啊操作完一个以后,它返回的就是操作完以后的这个stream了,你再去点limit就继续的可以去执行。这呢,我们也称为呢,叫方法链的一种调用方式啊,在这呢,就是你从那个结果当中取得前两个嘛。诶,没问题啊,好,这就过掉了,下边这个呢叫做skip skip的意思呢,就是跳过的意思,你可以跳过指定的元素,然后把后边几个元素呢给大家输出一下。行这块我们得重新的再去调这个集合的这个STEM这个方法,得到一个新的STEM是吧,因为上面已经执行结束了啊,然后呢,通过这个stream呢,我们去调下这个叫K这个操作,比如我这块呢,我写了一个。
25:12
然后呢,再去调一个这个for each system调out。哎,去打印一下。好,跳过前五个元素。来,我们看下这个结果。对,跳过前五个元素,这呢,我们就意味着从第零六开始的060708,哎,这不就我们说的后边这几个元素吗。哎,注意一下,诶同学发现我们一共呢就八个元素,那你说我这块要写个八呢。跳过前八个,乃至于说我这写个九呢。这个会不会出现这个类似于角标语界的问题呢?来,注意你看不会。啊,就是这块呢,如果我们只有啊N个元素,然后呢,这个呃,或者我们这不组N个元素,然后这块你写了个N,这块呢就全跳过了,跳过以后那就没有了是吧?就这样个场景啊行,比较好理解,这两个呢,一个叫limit,一个呢叫做skip,他俩有点像互补,哎,它呢相当于只取前四个,比我这写的四是吧,然后这块你就跳过前四个。
26:06
那加一起呢,不就是完整的这个集合的元素吗。OK,然后看下边这个啊,这个呢叫distinct,我们后边讲这个circle的时候呢,也会有一个叫驱虫的一个操作啊,用的也是distinct的这样一个关键字了,我们这呢是个方法,它呢叫筛选或者叫驱虫。呃,去除重复的元素就这意思,那去虫的标准是什么呢?这块是参照哈希code和ES2个方法来共同实现驱虫的操作的,那我们这儿也不陌生,那我们site里边呢,驱虫不就是按照这样的标准嘛,诶,效率会更高一些是吧?好,那我们当前的这个集合当中哈,你看我们从零一直到零八,针对于咱们这个employee呢,我这儿也重写了这个ES和。呃,和这个哈,扣的这个方法,这两个里边呢,就把咱们当前对象的这个属性啊,都参与去比较了,那言外之意的话呢,就是我们目前这里边的几个元素哈,他们都是不同的。
27:00
再注意都是不相同的,那回过来我们得整几个是不是相同的元素了是吧?诶我们在当前这个例子啊当中呢,我再去艾几个元素啊。比如说啊,我这块把它呢拿过来啊。诶粘过来这个呢,咱们写成叫10098。啊,换一个哥们儿。啊,最近的这个,诶,马斯克。啊,新闻呢,还是挺多的是吧,前段时间的话呢,自己发了一个推特说呢,他不会这个自杀的哈,他是怕别人把他给杀了。啊,据说呢,这个推特呢,他不是已经接手了吗?接手以后呢,里边发出来这个翻出来大量的一些,呃,民主党的一些这个这个私密的一些资料是吧?嗯,他怕被这个给他暗杀了哈,所以说他不会自杀,这个胆也小了,好像前两天又发了一个推特说,呃,是不是同意他辞去这个CEO的这样的一个职位是吧。啊,现在这个占的事儿不少啊。好,这个我们现在呢,把它呢,添加到咱们当前这个例子里边了,然后呢,我再诶复制一下啊,比如来四个吧,那显然呢,咱们当前这个例子当中啊,是不是有很多的这个重复的数据了啊,也就是这哥四个呢,这不就重复了吗。
28:11
啊,你也可以稍微在这块打印一下,咱们先稍微的搂一眼是吧,好这块呢,我就打印一下这个当前这个意思啊,嗯,这个看到的可能稍微的差点意思,因为写到一行了,有点长哈。这个往下走有点长,这个你往后找就行了,你看我们当年这里边儿这个马斯克这不有好几个吗。诶说明呢,我们当前这个list里边呢,确实已经有好几个诶重复的数据了,没问题是吧?好那么接下来的话呢,我们就要把这个重复数据呢,给它去掉,怎么做呢?List点咱们第二下这个stream的这个方法嘛。先得到这个stream,然后接下来的话呢,我就调这个调in,我就实现了一个驱重了,那驱重以后你怎么证明啊,咱们再去遍历一下呗。诶,所以呢,就就这样写是吧,诶搞定啊好,完事以后,此时我们再去做一个执行。
29:01
OK,然后这个呢,咱们就看一看,我上面这不有个换行嘛,换行之后的这个行为就可以了,那你看这儿从零一啊零二走走走走走零八,哎,0909这块马斯克,你看只留着一个,那意味着我们重复的另外的三个呢,这不就都给去掉了,这就是驱虫的这样一个操作啊。好,那么我们再回到咱的这个这块,如果你把这个code呢,给它去掉了。你看我给注入掉了是吧,那么此时的话呢,大家你想一下,如果咱们要是在这个sat当中存储的当前这样的几个元素,那很显然的话呢,我们此时的这几个是不是就认为它们是不相同的了。呃,因为我们这个黑的值呢,得到的就不一样了,是吧?诶,所以呢,我们这几个就都能存下了,那就意味着是不是我们此时呢,再去run一下,诶,你会发现呢,里边是不是也会有多个马斯克就进去了。没问题是吧,通过这个呢,咱们也能够证明啊,确实呢,咱们啊要求是。重写一下哈O和eo方法,哎,我们这里边这个比较的标准呢,也需要呢,用到这个哈O的这样一个操作。
30:04
啊,这个大家注意一下,这呢,就是咱们说stream当中这个叫筛选与切片这样的这个行为。那接着的话呢,咱们来看看针对于stream的这个叫映射的一个操作,这个映射呢,就跟咱们高中讲的这个数学的映射啊,其实是一个道理啊,那映射当中的一种特殊场景,咱们就称为呢叫函数了是吧?诶当时我们讲函数不就这样引入的嘛,在这映射什么意思啊,你比如说啊,咱们左边这个集合当中啊,我这有集合为例吧。我这呢,比如说放的叫AA,然后映射完以后呢,我希望你换成这个大写的叫AA啊,然后这个呢叫BB的话呢,诶这个映射完以后呢,就大写的这个叫BB了。诶,所以这块呢,中间这个映射关系呢,我们要统一的去表达一下,相当于呢,就获取左边这样的这个字符串呢,它对应的这个大写的一种表示方式是吧?诶或者的话呢,你比如我左边写个123.45,诶右边这块你诶四舍五入以后呢,就123了,诶123.5这块四舍五入完以后呢,就变成124了,这个呢,你可以理解成就针对我们左边这样数值类型的这样的一个数据,转化成它对应的这个四舍五入的一个场景。
31:05
诶这呢,中间的映射呢,就是一个wrong操作了OK啊行,那左边是一个什么,右边应是个什么,我刚才举的这是例子啊,还比如说呢,我们左边如果放的叫employee。放在相当于叫员工是吧,然后右边呢,我说呢,可以映射出来这个员工他所对应的这个名字,比如这个员工呢,他的名字呢,叫Tom。那右边映射出来的这个类型跟左边类型啊,就可以不一样。啊,这块大家呢,也可以去注意一下啊,行,那么下边我们就可以写一下关于映射这里边这个操作了,这个映射呢,咱们用的叫map,这个map呢,咱们前面讲集合的时候呢,提到过一个接口是吧?诶这个我们有键有值啊呢,映射值其实上也可以理解成就是一种映射关系了啊。好,那我们内部呢,接收的是一个function式啊,也很好理解,那方式的话呢,不就是传一个自变量,返回一个因变量,这不就对应的我们,呃,映射的一个是自变量,就是左边的,然后函数呢,呃,Function式它对应的这个抽样方法的返回值就是我们这个因变量嘛。
32:02
OK啊,比如说咱们直接呢来写这个例子了,说呢,我们需要呢,将当前这样一个例子当中这个元素啊转化成大写,呃,你给我显示出来啊,这个怎么做呢?看啊首先呢,这块已经有这个例子了,我们直接呢调这个stream这个方法,是不是首先得到我们stream这个实例了,对吧?然后接下来的话呢,我们就进行中间的这个操作了,咱们使用的这个叫map啊。好,那么此时这个map这块。啊,Map这块呢,诶大家呢,要反映出来它对应的这个抽样方法叫做apply,传进去是一个string啊,返回的这块呢,你看在这不确定啊,其实我们相当于还是一个string类型的,哎,你看我们这块怎么去写啊。哎,现在于现在你看我们得到是不是这个字符串是吧,我希望呢,把这个字符串呢,是不是叫哎,To upperca啊。诶要我们这样个方法,诶是不是就可以了呀。啊就搞定啊,然后最后的话,我们针对当前这样的一个结果,咱们再做一个终止操作,把它呢,做一个便利的一个。行为就行了。
33:02
哎,这样就可以了。行里边呢,就这样的去实现就行。哎,稍微带大家去体会一下这样的情况啊,好先呢,做一个run。嗯,你看这块呢,我们就把这个abcd呢,转换成对应的这个大写了啊行,但是你再看我们这样写行不行啊,怎么着呢,我把里边这个凑呢,我给它去掉,我换成了叫string,然后冒号冒号啊叫two upper case,诶走起你发现了A也可以是吧。呃,相当于上边的呢,是一个拉曼表达式,下边呢,是不是就我们说的叫方法引用了啊。两种方式都可以啊,下边这块看着是不是有点懵?啊,这个怎么去解释呢?诶我们map里边要求放的是一个function,这个function的话呢,对应的这个出方法,你看长这样子是吧,好,那么再回过来啊,然后呢,这个方法跟我们现在要调的这叫to up case,你看啊,咱们这个to up case的话呢,没有传参数啊,反应类型是个string,诶跟这个数不对应啊,诶相当于我们现在使用的就是咱们讲的方法应用的是不是第三种情况呀。OK,没问题啊,这里边的话呢,它相当于如果有N个参数,我我们这个呢,呃,调的这个叫up case呢,这不就N减一个参数啊,你这块其实是一个参数,我们这块不就零个参数嘛,然后呢,你这个呢,填的这个是string类型的,恰好呢,作为我们这个to up case这个调用者出现的啊,就是对应的我们这个情况三。
34:16
啊,所以回过来,哎,我们就是这样的一种格式啊行,大家呢,找找感觉。啊,这我写成叫方式一哈。哎,这个呢叫哎方式二。诶,这就这样啊好,下边这个呢,我们说叫获取员工姓名的长度大于三的员工的姓名。诶这块注意啊,咱们落脚点呢,叫员工的姓名,那做这个练习之前呢,咱们先做一个这个练习吧。要获取员工姓名的长度大于三的这个员工。呃,他的这个信息。那这个落脚点呢,叫员工是吧,好,那么首先的话呢,咱们先得叫employee data.get employees先得到咱们当前这样一个历史集合,然后呢,第二调这个stream这个方法,拿到一个的一个实例。
35:09
啊,咱们上面有这个例子了啊,咱们这个改个名叫employees。就可以啊。好,调这个string方法呢,得到STEM的一个实例了,接下来诶,我们现在呢,是不是要做一个filter的一个行为啊。过滤嘛,诶过滤什么呀,诶这呢左边呢是叫员工,哎,然后呢,得到的是一个布尔类型的值,我们叫get它的name是吧,它的这个,嗯,接着呢,是不是获取这个它的长度啊要求呢得大于三。是不是得这么着啦,然后我们再去做一个for each的一个便利。那这呢,我们再写成是一个。哎,这个方法引用是吧。行,这个能看懂吧。啊,就我们写的这样一个操作,这呢是一个顾虑行为啊,没有用到我们这个映射,因为呢,他的落脚点呢,仍然是叫做员工啊,所以你看我们得到的都是这个员工,诶这两个人他的这个名字呢,长度呢是大于三的。
36:03
没问题是吧,OK啊。哎,这个你要愿意回过去看一眼就看一眼啊,这不只有呢,比尔盖茨和这个扎伯格嘛,是吧,OK啊。这个做完之后呢,我们再接看下边这个需求,这个需求呢,咱们落脚点呢,是到一个string的这个层面了,所以我们需要做一个映射哈,来我们基于刚才这样的操作呢,我再拿过来。比如说呢,我们先去做的过滤,诶过滤完以后呢,我们就得到了是员工,呃员工呢,是姓名长度大于三的这个员工,然后呢,我们要映射到什么情况呢?就是左边呢,如果是员工右边我们映射到他的这个内幕是吧?所以这块map的话呢,我们这边去写,怎么写呢?左边是员工。呃,映射完以后呢,是不是员工的get他的这个name就可以了。那不就这样来写吗?啊,这个注意一下是吧,就这样来去实现啊好,那这个写完之后呢,我们再去做一个软执行。好,大家看这时候呢,你看咱们得到的就是纯粹的是这个字误串了。
37:01
哎,这呢,就咱们这道题的一个写法,当然了,哎,有同学可能会说说我能不能这样呢。什么意思啊,说呢我就先啊,咱直接复制一份吧,我先做这个映射是吧。我先做这样的映射,那你映射完以后注意看啊,我映射完以后的话呢,是不是就得到的是员工的姓名了是吧?然后我再顾虑的话呢,是不是就针对这个姓名,然后去做看谁的长度大于三就行了,所以这块你再映射这个是没问题的啊,只不过这个类型呢,你考虑一下,它已经不是咱们说的叫诶employee类型了啊,其实就是个name了是吧,所以这块咱们就把它改一下了。直接呢,就是这个name的这个长度呢,诶大于三啊就可以了。哎,是不是这样也可以啊。没问题是吧,哎,这块大家注意一下这样一个情况啊,这呢就是咱们写的这个吸烟过滤也行,先烟映射呢也可以好这个写完之后呢,大家也在想啊说呢,我们再以刚才写的这个为例,我再复制一份哈,嗯,这个位置呢,呃,稍微大家再搂一眼啊说我们能不能就写成叫employee,然后冒号,冒号叫get一个name呢,发现也行是吧。
38:09
看是不是懵了啊,上边这块呢,我写的是拉表示,下边这块呢,我就改写成了叫方法引用。啊,这个呢,还相当于咱们讲的方案营的这个第三种情况。啊,这个我不用多去说了啊,哎,还是相当于第三种情况啊,所以大家呢,体会一下,哎这呢是咱们说的这个叫哎方式一是吧。嗯,这块我们写一个。哎,方式二啊。诶方式三啊,稍微的感受感受,其实你可以把这个呢,就是这块也调一下呗,那也可以就相当于四种方式了是吧。好,这就过了啊,然后呢,这是映射啊,这呢算是比较长的一个操作了,接着我们看这个第三波啊,中间操作叫做排序啊,涉及到这个排序的行为了啊,你比如说我现在呢,呃,咱们以数组为例吧,我这是一个in类型的数组,或者是一个string类型的数组,呃,希望呢,你给我做一个排序的行为啊,针对哪个都可以啊,你比如我们针对这个AR啊,他来讲,首先呢,我们先得到一个stream的实例啊,我们提到了A瑞点是不是调这个方法呀。
39:15
然后把这AR呢,我们扔进去,这样呢,咱们不就得到了一个吗。诶至于说呢,你这块我又不想要他这个呃,反回值的啊,因为呢,反正你每次用也只能用一次嘛,诶直接就在后边调,实际上也行是吧,好这个我们就直接呢调了调S这个操作。排序了啊,排序完以后的话呢,我们再去做一个for each的一个便利。诶,是不是就这样个行为啊,没问题啊好,这时候呢,我们做一个run执行。哎,这就出来了,但是你会发现呢,我们针对这个叫in特类型的这个数组,咱们就做了一个升序的一个排列,诶所以这块呢,只要涉及到排序的话呢,就是咱们前面讲的两种排序方式啊,一个呢叫自然排序,一个呢叫定制排序,这呢因为你没有传任何的compare这种事例,所以它就是一个自然排序,也就是我们所谓的叫声序了。
40:05
好,那我问大家一个问题哈,你看我们现在呢,这个呃生据呢也排列了,呃,你说我们这个A2,它本身它的顺序变了吗。啊,你比如说我这个,我咱们不是有个叫图方法,我把这个AR呢,是不是扔进去,把这个AR呢,相当于是不是可以做一个便利了,是吧,好你说这AR呢生去了吗。还是说呢,它是原来的这个顺序呢。啊,这个咱们前面没提这个事儿是吧,来走一下啊。嗯。好,大家看这个时候你会发现呢,我们再去打印这个AR的时候呢,还是原来的这个数组这个样子,诶不是说给他升去了吗?怎么这块没有升呢。哎,这块大家一定要注意一个问题啊,回到我们这个0PI这块,你看我们这里边有一个二。嗯,这个二呢,说stream呢,它不会改变这个语言对象,相反他们会返回一个持有结果的新的stream。嗯,也就是说啊,咱们此时呢,针对于以这个数组为例,它的一个排序操作呢,只是说呢,你这个返回的这个salty的方法得到了一个stream,这个stream呢,是排序以后的,应该去遍历了一下。
41:13
啊,并没有针对我们这个容器本身产生任何的影响。啊,针对咱们前面讲的这些呢,也是同样的道理,你比如说哈,咱们讲的第一个叫filter叫过滤是吧,我们得到了当前这样的一个集合,这个集合的话呢,咱们做了一个过滤的行为,诶我们在做一个便利,发现在里边就只有个别的几个员工了,但是注意哈,咱们这个集合里边还是呃,最初的你这有八个员工。他还是这八个。不会说呢,因为你这块你过滤完以后,说我这里边儿是不是就剩几个了,不对,集合里边还是八个,所以说咱们下边你看再去通过这个集合再去调stream的时候呢,是不是还是拿着你这八个重新来的呀。而不是说呢,在你上面操作完以后呢,针对这个集合呢,产生影响了,并没有是吧,这就我们提到这个事儿啊,它不会改变本身咱们这个原对象啊,也是我们这个数组或者集合。
42:04
OK行,回过来啊,这儿呢,我是针对于这个数组这个AR啊,来去做了一个升序排列啊,那同样的啊。比如我们把这个删一下,我在这稍微说一下啊,说诶我们AR这个数组啊,并没有啊。因为啊,生畜。啊,做调整。啊,这个大家一定要注意啊,好,那么针对这个are呢,呃,也是类似的道理啊,你这个A。二我们调这个叫方法,然后把是吧,然后我们再去做一个用,然做一个。哎,这个普,哎这不就可以是吧,哎类似的这个道理啊,比较简单。嗯,下边这块你看实现了我们针对这个字串的这样一个升序嘛,弟弟哥哥姐姐妹妹嫂嫂是吧,哎,就出来了啊升序。
43:02
好,这个完了以后,那接下来大家你看啊,我们现在呢,是不是有一个啊叫employee啊,有一个方法叫employees,它呢就能够得到一个具体的一个集合了。啊,那么你说我们这个集合,我现在调一下这个STEM,这个操作得到一个STEM,哎,然后接下来我去调这个salty,这个操作调研完以后呢,我们也去做一个each,靠谱吗。这个靠不靠谱,靠不靠谱取决于什么呢?取决于咱们这个employee啊,目前有没有去实现自然排序,大家你会发现是没有。好,那既然没有,那么回过来,当然你看一看啊,此时呢,如果我们再去调这个这个操作是不是说就会报异常了。啊叫class exception说你当前的这个employee说不能够转化成是。啊,这个呢,咱们只要涉及到了这种排序啊,你没有去传这个comp这种场景都是自然排序啊,自然排序就要求你当前这个类呢,是不是得实现相应的这个接口是吧?诶我们在这写一下啊说因为啊,咱们employee没有实现啊comparable这个接口,诶所以。
44:11
哎,这个报错了。啊,这个大家要注意一下这个场景啊,好把它注入掉。行,这个呢,上边我们针对这个针对string,人家呢都已经实现了able接口了,所以说呢,就能够实现自然排序啊,这个很好理解,好,那针对于咱们这个employee的话哈,放在这个集合里边了,如果我们就不打算让它去实现那个接口了,那你只能是定制排序了。怎么做呢,也比较简单,先把我们这个集合呢,先拿到通过这个集合呢,咱们去第二下这个叫STEM这个方法,然后呢,此时呢,你写这个S的时候呢,你就别什么也不写了,是不是就此时呢,指定一个compar的一个实例就行,那comparable呢,又因为呢,哎compar呢,又因为它是一个函数接口嘛,所以这块我们就可以使用这个拉姆达表达式了。所以大家脑海当中你要浮现出来compare它的那个抽象方法长什么样子,诶脑海当中,诶应该能想到啊,我们是不是有两个参数是吧,然后呢,我们要干什么呢?比较一下它俩的这个大小,怎么算大怎么算小。
45:12
嗯,咱们回过来,比如说。我们看一下什么呢,看下他们这个A吧。是吧,看那age说谁大谁小,哎,按照从小到大排行,那么咱们回过来,那就是一一.get一下它的age。然后呢,去减去e2.get它的A,那这呢是不是就可以了?好,那么给了这样的一个标准之后呢,我们就可以呢,做一个for each的便利了。哎,这不就搞定了吗?呃,这块大家体会一下啊,这呢就写了一个拉姆达表达式,那此时我们再去做一个。好往后走,我们看一下是不是就按照这个A呢,从小到大的顺序呢,给排列了呀。哎,没问题,那就这样来去写啊,这个大家稍微的注意一下。好,那么这儿呢,咱们就把这个salty的这个情况呢,就讲清楚了,如果你要针对我们上面这个string啊,你说我想按照从大到小排这块呢,你也可以呢,是不是传一个compit显示的,指明下谁大谁小。
46:08
没问题吧,啊举个例子啊,比如呢,诶针对于这个,嗯,字符串。哎,从大到小。来排列,这个呢,相当于又回归到咱们前面讲的这个自然排序和定制排序他们二者的一个区别了啊好,那么这个A。第二咱们第二这个思方法,我把这个A21扔进来了,A进来以后呢,呃,如果呢,你不想按照它指定的这样的一种升序来的话呢,里边你可以传一个具体的一个,诶我们说的一种排序的方式,你如果想降序啊降序那就降序,这里边呢,有两个字符串,一个叫S1,是不是一个叫S2啊啊针对他俩的话呢,如果你还是写的叫S1COMPARE to s2。这样的话呢,其实还是一个升序吧。那我们再给它打印一下是吧,这还是个升序哈,那你可以在这个位置是不是加一个符号就可以了。那我们就做一个降序的排列了。
47:02
好,这时候大家看一下,这不就是降序来吗?没问题吧,OK啊行,稍微的大家呢,去体会一下这样一个场景啊,嗯,这个要完了以后呢,你再看哈,现在咱们这种写法里边,我能不能给他改造一下呢。String啊,冒号冒号叫compare to,你发现他写完之后,诶也可以是吧?哎,这是不是又是一个方法引用了。呃,这个呢,对应的是咱们方案营的,是不是还是第三种情况。啊,因为呢,我们这里边你看咱们呢,要呃,针对的是这个它的一个它的一个实现啊。它这个实践的时候呢,它对应的这个叫compare的方法,两个参数啊,一个in的极值啊,返回值,我们这儿呢,是不是只有一个参数。啊,然后呢,你两个参数的这个我说大家能理解吧。你看我们这个这里边是不是咱们要写的是这个方法是吧,这不俩参数吗。啊,回过来啊,这两个参数我们这儿呢,是不是只有一个参数,诶,你的这两个参数的第一个参数作为我们的调用者出现呢,诶这不相当于用的这种场景吗。
48:05
啊,这个大家体会一下啊呃,但是这块呢,我们调的话呢,这就相当于是一个升序了。啊,这个你得小心一点是吧,这是相当于是个升序的一个场景啊。行这块你说我们加个符号。啊,这不行是吧,那成了你在这个方法里边加个符号,他就不认识了啊,所以这块呢,我们现在就是一个升序来了,你要说我就想这个降序,那你就还是这样去写啊。这是我们说的,这个叫中间操作,这个叫排序。好,那么继续啊,咱们接着呢,来讲咱们这个STEM这个操作,刚才呢,咱们是把这个中间操作呢就说清楚了,然后接下来啊,咱们再讲一讲,这个叫终止这个操作啊,诶终止操作首先呢,我们来看这个课件啊,找到我们最后的一个叫终止操作,终止操作这块呢,我们分成了这样的几波,第一步呢,叫做匹配与查找,诶相关的你看有这样的一些操作,第二类呢,叫做规约的这个操作reduce,第三类呢,叫做收集,OK,主要的就是我们说的这样的三波啊。
49:01
好,那么回过来。诶刚才呢,我们也提到了一个点哈,说呢,针对于我们这个STEM,整个这个操作流程啊,是有三步的中间操作呢,我们说诶执行完以后呢,一定要去调这个终止操作,否则呢,这个中间操呢,它是一个惰性求职的过程,也就是说呢,你要不写终止操作,就没有这个中间操呢,它就不执行,咱们刚才呢,在讲这个中间操作的时候呢,咱们都是以一个固定的终止操作来讲的,这个呢,叫做for each。那么除了这个for意识之外,还有哪些终止操作呢?这个就咱们现在要讲的这个点是吧,先看第一波,叫做匹配与查找,OK,这呢,你看列举出来了一些具体的一些操作的行为啊,一个一个来,首先看第一个,这呢叫all match。那是不是都匹配的意思,嗯,来我们写一下这里边儿,比如说诶是否所有的员工的年龄呢,都大于18岁。针对于咱们啊,前面提供的这个employee data说看年龄呢,是不是都大于18岁啊,显然这块不满足啊,云比较小是吧?呃,那回过来怎么做呢?首先啊,通过我们这个employee data.get啊employees先得到咱们这样的一个集合。
50:07
啊,这没毛病了哈,然后拿着这例子呢。诶第二诶,我们接着呢,去调这个stream这样一个方法,诶这不就得到一个stream了吗?那我们呢,呃,得到stream以后可以没有中间操作,直接咱们就调用这个叫终止操作,这是没问题的,所以我就直接呢去调叫all match。O里边呢,你看predictdic是不是又是一个函数接口?哎,那只要出现函数接口了,你就可以使用拉姆达表达式,脑海里当中要清醒啊,这个接口的抽象方法,哎,还记得吗?是不是叫做test呀?哎,所以脑海当中你得清晰啊,只有你浮现出来这个结构了,我们下边写起来才更容易一些,但在这T里边呢,针对这个TT谁呢,就是我们这里边这个employee了,所以呢,你就这块写employee。哎,然后呢,干嘛呀,匹配一下它的这个,呃,Get age是不是都大于18岁,哎,就这个场景,它得到结果呢,是一个布尔类型的,咱们就直接呢,做了一个输出了,哎,我就这样来写了。
51:03
OK,来,走起。嗯,这呢是个force啊,因为咱们刚才看到马云的年龄比较小是吧,是两岁啊,所以这块呢就不满足了。行,回过来,下边这个呢,叫做any match。Any的话呢,就是是否至少有一个匹配的。啊,只要有一个就行啊,你比如说咱们还以刚才这样的一个场景来说啊,CTRLC一下,诶我呢把这个呢,咱们在原封不动的拿过来这块呢,相当于是判断一下说,呃,员工年龄是不是存在着大于18岁的。多了一个练习啊。说这个,呃,是否存在。嗯。呃,年龄。哎,大大于18岁的。这个员工。呃,这块的话呢,我们把这个or呢改成是叫any啊就可以了。那很显然的话呢,我们很多的员工呢,都是大于18岁的,所以只要存在一个就行啊,也就是说呢,这个结果呢,就是一个触吧。
52:03
没问题是吧。来体会一下啊,哎,这个all和any啊,这个我们后边在讲这个SQ的时候呢,也会有类似的这样的这个行为,在多行查询的时候呢,我们会有这样的点啊呃,多行查询啊,类似于我们这里边多个数据,你比如说呃,现在呢,这个过年的时候啊回家。这个七大姑八大姨给你介绍这个女生是吧,来说这个女生的话呢,就比较贤惠啊,知书达礼啊,这个呢,学历比较高啊,属于这个智慧型的女生啊,这个呢,就属于这个甜美型的是吧?呃,说的你挑一个吧。啊,你说这块呢叫哦。Or是什么意思啊?就是都想要是吧,哎,这就是all的意思了,那安呢?那any就是你不挑是吧?哎,随便一个都可以啊,这就是any的意思啊哦,Any啊,体会一下。所以这里边儿这个all的话呢,就是所有的都得满足,Any的话呢,只要有一个满足就可以。嗯,OK。
53:01
诶,然后呢,我们来看这个需求啊,说呢,是否存在员工的工资大于1万,也就是说呢,只要有大于1万的就行,是不是用any啊。OK啊行,所以呢,首先list.stem这个操作注意啊,咱们这个一定得从头去调这个stream,你不能拿着现成的一个STEM接着操作,因为一旦执行了这种终止操作了,你就不能再去调了,是吧,前面已经说过了啊。呃,他这要干什么呢?说any match哈,说是不是存在工资有大于1万的啊,那就是这块呢,是员工,然后呢,员工的get,他的sal呢,大于1万,诶这样就行了,得到一个布尔类型的值,咱们直接打印。然后回过来看一眼,1万的。诶没有是吧,诶那这块你看都不满足,所以回过来我们这儿的结果就是一个false吧。嗯,你看这就是行,再回过去,比如我们这边改一下啊,诶马云的这个工资啊,两岁,然后呢,就9000多块钱了啊,挺多的,我们给他加个一啊19800。好,那么再回过来,我们做一个执行。
54:02
嗯,你看这时候呢,就是出了啊,因为呢,只要有一个满足就可以啊。行,这呢是我们说的这个场景下边这个呢,叫find first啊,返回第一个元素啊,这个呢,比如我们还是拿这个绿色点,咱们调一个这个stream是吧,然后呢,我们就直接呢叫find first。那就掉它了啊,然后呢,直接我们做一个打印行,就找到这个,呃,STEM当中的第一个元素是谁就行。执行这呢,因为咱们没有写这个中间操作哈,那这里边儿的第一个元素就是我们找到第一个了,诶大家呢,你会发现呢,此时呢,诶咱们这个结果好像不是一个employee是吧。啊,确实如此啊,它返回的结果呢,是一个optional,这个optional的话,咱们在哪讲呢?在这个APIAPI里边啊,这块第一个咱们就说一下这个optional。OK啊行,诶目前的话呢,如果你要是想,呃说我就想拿到是一个employee,那你就再调一下这个盖的方法就行,通过optional其实也是一个容器哈,里边儿呢,包了一下咱们这个employee了,第二代get呢,就拿到这个employee了。
55:02
OK啊,后边的话呢,我们再专门说一下这个optional它的一个使用。然后这块的话呢,我就没有写这个中间操作哈,大家你也可以呢,通过我们这个stream的话呢,你再去调,比如说刚才我们讲过的这个叫排序的操作啊,你排完序以后呢,你再去获取排序以后的第一个啊,是不是也行啊。OK啊行,这呢,就我们说的这叫find first这样个行为,接下来这个呢,叫做count啊,这个是求个数的啊,那我们比如说还是。找到我们这个an employee.get employees。呃,先返回一个这样的list是吧,诶list点调我们这个STEM这个方法,诶然后呢,直接我们就来一个count的调用了,直接打印在此时呢,就相当于获取咱们当前这个历史对应的这个stream当中的这个元素的个数。站长应该有八个是吧,诶咱们也没有其他的中间操作哈,你也可以去加,比如说我先去过滤一下啊,过滤一下我们这个员工啊,他的get一个,比如说三吧,诶。
56:02
大于7000块钱的。呃,大于7000块钱的这个员工的个数,你看有几个。啊,这呢是一个终止操作。那也行啊,那这时候就有三个是吧,OK啊行,这呢是我们说的这个叫count了,下边这个呢叫max,里边呢传一个compor,就是按照我们这个比较器比较完以后啊,或者叫排完序以后是吧,然后呢,最右边这个呢,其实就是所谓的最大的,然后这个min的话呢,就是最左边这个呢,就是所谓的最小的。比如说看第一个需求,那呢,返回最高的工资。嗯,返回最高的工资,注意咱们这个落脚点呢,是工资哈。啊,其实稍微有点难度,哎,你要是不太好做的话,你先做这样的需求啊,这个什么呢,要返回。最高诶工资的叫员工啊,这个需求呢,要简单一点。差一个什么呢?诶差一个映射啊,诶写一下类色点,我们先调这个STEM这个方法,得到一个STEM的一个实例了,诶然后呢,诶我们现在要找这个STEM里边呢,这个最大的是吧?哎,这就取这个叫max了。
57:09
呃,咱们这里边儿呢,呃,大家脑海当中要浮现出来我们这个compare它的对应的一个参数了,参数呢,是不是有两个,一个叫呃一一,一个叫一二,就是我们叫员工了是吧,我们想获取他们这个工资的,呃谁高谁低,呃这个你比较的这个原则不就是按照工资来吗。1.get他们的这个salary啊,这个我们要调的话呢,是不是就想起来调这个double了是吧?第二他调这个compare方法,呃,E1.get它的salary啊e12.get它的salary诶这不就可以了。这呢,就相当于我们传了一个叫compare,它的一个实现类的对象,用拉表示来写的啊。嗯,这不就完了吗?他要落脚点不就是员工嘛,那我们直接呢,就诶输出一下不就行了。那就可以了啊,来,走起。嗯,你看这个他得到的也是一个optional啊里边呢,就是我们说的,诶,马云的工资你看最高的。
58:02
啊,实际情况呢,这块也确实啊,就他的这个高是吧,OK啊行过来,诶这块呢,你要愿意呢,剥滤出来我们这个employee你就调下这个get方法就行啊,我这就暂时先不调了啊。行,大家看看这个呢,是不是清晰。啊体会一下啊,其实主要呢,就是提供这样的一个。实现类是吧,好,然后呢,接下来诶,我们下边这个需求,你看一下啊,他那叫返回最高的工资是多少。啊,最高的工资是多少?哎,那当然有同学呢,可能会说说这个呢,我我会整是吧,你现在呢,不是已经得到我们当前的这样的一个啊,这个叫啥了。啊,我看这个括号对不对啊,少个括号吧,行,当前呢,我们已经得到那个最高的,其实呢,目前是一个optional,然后点一个这个get,这就得到employee了,然后再去get它这个salary。是不是这也是一个思路哈。哎,这不就是最高的工资,就找到了也行。嗯,还是马云啊,这不就是19876块一毛二是吧,诶这个也行,或者说的话呢,我们还可以做一个映射吧。
59:07
哎,这个我们叫方式一啊。哎,这个我们叫,哎方式二啊。你看啊,下边这块呢,咱们做一个映射啊,我没有使用这个map,下边咱们用一下这个map。啊,类似的点,呃,咱们调这个stream点,咱也咱先呢调一个这个map的行为啊,先映射一下啊呃,因为你这块注意咱们这个max的话呢,它是一个终止操作,你必须在终止操作之前呢,先调这个map啊,不能调完这个max再调这个map就不合适了啊。好,这个映射的话呢,我们左边呢是员工,右边的话呢,是我们找到员工,他的这个叫呃工资是不是叫salary啊。你看这就可以了,好,那映射完以后呢,我们得到的其实就是啊一个一个的工资了,然后咱们再取这里边这个最大值是吧,这个最大值的话呢,注意此时代画呢,是这个叫诶SALARY1诶和我们这个SALARY2了。
60:00
然后这块呢,我们再去调一下这个是吧,把这个ary。啊,SALARY2,诶是不是扔进去就行,哎,这样的话呢,我们就得到这个结果了,咱们做一个输出。啊,看看是不是能hold得住哈。来,走起。嗯,好,大家看,诶这个呢,我们就拿到这样的一个结果了嘛,诶这块还是一个optional啊,你再调下这get呢,就拿到它了,行,这个我就调,调不调这都行,这都比较简单了哈,实际这块愿意调你就get一下就行啊get呢就获取这个optional里边呢,实际呢,它包着的这样一个数据啊,我们这儿呢,不就是工资嘛。就出来了,行,这就完事了啊好,这个写完之后的话呢,我再复制一份哈,因为呢,大家你看我这个位置哈,我这样写的啊,这个大家写多的话,你就有感觉了哈,我就想直接用double冒号,冒号来一个。哎,这是不是又是一个方法引用了。OK啊,因为在我这个max里边呢,你看我们要调的是这个是吧的话呢,诶它对应的这个方法,这不长这样吗。
61:01
把它我们盯一下这个回过来,它呢,这个方法我是不是就可以使用这个compare做替换了,你看这时候呢,两个参数,两个参数反类型都一样,我们此时对应的是咱们讲的这个方法引用的。哎,是不是第二种情况。这个回过来。啊,所以呢,我就可以直接这样写了。啊,体会体会,那比我们上边这个是不是就短很多是吧,OK。啊行,越简洁的话呢,肯定是相对来说不太好理解啊,从那个可读性上来讲呢,似乎呢要差一点,但其实大家要写读的话呢,其实你就知道呢,可读性其实还挺高的。啊,因为以前你看我们写这个发言的时候呢,你要是写。啊,一写是不是得写挺多。啊,那你想我们这块呢,要再去写,你看一行就全搞定了。啊,其实可读性呢,按说是更高了啊,只不过呢,大家刚开始写,刚开始接触可能不太熟啊,接触多了以后呢,其实这就清楚了。好接着来啊,看下边这个说呢,这个叫命啊,说返回最低工资的员工啊,这个咱们刚才做了一个叫最高工资的员工,这叫最低的,其实呢,这个套路是不是一样啊,你把上面这个CTRLC呢直接粘过来,你把这个max呢,是不是改成个M就可以了。
62:13
来,走起啊。啊,这是最低的啊,扎克伯格最低啊,这个两千五啊,年龄不小了,两千五是吧,回过来搂一眼看看是不是。2500,哎,对,就他最少啊,行,没问题啊。哎,这个咱们就过了。然后看下边这个啊,这个呢叫for each for each呢,就是咱们刚才呢,讲这个一系列这个中间操作的时候呢,咱们都拿着这个for each作为一个终止操作呢,给大家做的演示,它就是表示便利的意思了。啊回过来啊,行,诶,那这个简单来写一下啊,通过这个例子呢,咱们调string方法,调这个for,呃,没有任何的这个中间的操作,我们直接呢就来终止操作了,干啥事呢,咱们就想做一个便利传一个consumer,典型的这个consumer呢,它的一个。诶方法引用啊,或者我们叫一个替换,不就是打印一下吗。
63:03
对吧,诶这个方法跟我们内部的这个叫呃消费的这样一个方法,它不就是对应的吗。哎,这个方法不就长这样吗?我们传一个print是吧,传一个数据,然后呢,把它打印一下,然后呢,没有任何的返回。这个我们直接跑一下就行啊。嗯,这呢,不就是全部呢,都打印一下呗。就这个情况。没问题啊,像这个说完之后呢,想给大家再多说一句啊,这个咱们说呢,针对于这个集合啊,咱们说呢也啊在JDK8当中啊,增加了一个便利的方法,什么意思啊,你看啊上面这块呢,咱们是不是得到一个list。啊,就是纯粹在咱们这个,呃,调理方法得到这个例子啊,在这个及格当中啊,它增加了一个方法叫做for each。注意啊,这时候这个方法呢,是在我们这个集合里边增加的啊,这个还写到这个里边了啊,咱们这个例子呢,是实现了这样的一个这个接口了,Collection也实现了啊好,那么这块的for each里边仍然传的是一个叫consumer。
64:06
哎,所以呢,我们是不是仍然可以啊,诶。哎,又跑哪去了,写错位置了啊,把它的CTRLX拿走。咱们写哪儿去了?写这儿是吧。在这啊好,咱们仍然呢,是针对他呢做一个便利,所以呢还是写这个。啊,方法引用。就这样写就行。啊,这个大家呢,注意一下,以后呢,咱们再去遍历这个,诶collection的时候呢,我们就直接呢,可以写这个叫for each了。可以这么着,来啊来,走起。你看我这块呢,是不是又便利了一遍。看是不是这一套嘛。所以呢,这块大家你考虑一下,比如说啊,咱们针对于这个叫例子来说吧。哎,便利的这个方式啊,你想我们有几种,第一种,哎,是不是咱们讲的叫使用迭代器是吧。
65:06
啊,然后第二种呢,我们叫增强for循环。哎,然后第三种,呃,咱们讲的这个,哎一般的这个哎for循环,那现在呢,我们现在又引入了一种,就是它内部的一个叫哎for each这样个方法,哎也可以,你看这个结构呢,多简洁。一行代码搞定,原来呢,我们这个还得写好几行,这也是这也是这个都简介。啊,所以说大家掌握这个方法,引用拉麦表达式的话呢,确实啊,有助于提升开发的效率啊。找找感觉,接着咱们再看这个下边第二步啊,这个叫规约啊,规约什么意思呢?来我们看下这个题目啊,诶,Reduce就是规约它的一个词,翻译过来的一个意思啊,然后呢,这呢有一个叫T的,一个叫identity啊,相当于这是一个种子啊,后边呢,叫boundary operator什么意思啊,说可以将中元素反复结合起来,得到一个值啊,返回一个T。
66:01
比如说第一道练习说呢,计算一下一到十的自然数的和。哎,那我们这块呢,首先得得到十个数吧。啊,咱们比如说这样吧,AR as least。啊,123。四五六七八九十,这呢,我们就数构成的一个list。哎,没毛病是吧。好,那么有了这个例子以后呢,我想先得到一个stream,然后呢,我去调一下这个叫reduce。我们调这个是吧,那reduce这块的话呢,我们先就调这个操作吧,它这前面呢,填一个T类型的一个N啊identity这什么意思啊,那你就可以当成一个叫初始值也行。啊,这个我就先写成是个零了啊,一会儿来解释,后边这块呢,要传一个呢,叫boundary operator,这哥们呢,没见过是吧?没见过呢,咱们就点开lo啊,再点开它是不是叫boundary operator吗。诶,他呢,你发现是继承一叫拜function。哎,方式呢,咱们熟就是一个函数嘛,这个BY方式呢,它相当于是有两个自变量的啊,你看它其中于这个,你看这写了一个七,这写了仨是吧,哎,你把这个点开这个里边呢,不就是长这样吗。
67:15
哎,相当于咱们这个函数呢,它有两个自变量,然后得到一个因变量嘛。没问题是吧,好,那么回过来呢,他这儿呢,只需要传一个气就行,呃,大概心里边儿有数了。哎,大概应该心里有数了啊,我们现在的话呢,针对这个是integer,所以呢,此时的这个T啊,U啊,R啊,其实都是integer啊,嗯,这儿呢,方法你看参数长这样,那咱们就也整个小括号呗,一个呢叫X1,一个X2。不就这样呗,哎怎么办呢?哎,把这个S1跟S2是不是加起来就行。哎,加起来就作为我们这个方法的这个方法体啊,Return下它俩相加,第二呢,返回的就是它俩加的这样的一个元素的类型是吧。类型。完事了啊。
68:00
然后呢,直接我们做一个输出。带走起啊。好,这个呢,结果就出来了啊,55,这个一到十加一起就是55。就这个意思行啊好,我这儿呢,再稍微复制一份这个位置呢,比如说我改成是十了。嗯,当然你看一下它的一个意思。结果就变成65了,所以呢,它可以看成一个叫初值,或者说我们理解成就是一个种子是吧。这个种子跟咱们前面讲那个UR不一样啊,这个呢,就是最初的这两个值在它的基础之上呢,我们做相关的这种迭代啊OK。好,这呢是我们说的这样的一个题目啊,这个说完之后呢,我还想再整点花活是吧,诶怎么整呢,你看啊,呃,此时呢,咱调的是加法,我们在这个里边啊,它也有一个方法呢,就叫做sum啊,这个sum的话呢,诶我可以这样来去写。这个首先大家能理解吧。就是我不自己加了,我第下这个特有个sum方法,把这两个放一起加起来一个道理是吧。
69:05
来还是55 OK,那有这样写的意义是什么呢?我实际上呢还是想变的啊,大家你看我们此时要诶重写的这个咱们呢是叫ary operator,刚才咱们也看到了这哥们啊,他呢是继承于这个的,这个呢又是实现的,诶继承我们班ary function这个接口长这样是吧。好,那么回过来长这样的话呢,你看跟我那个萨呢像不像。像啊像像的话呢,是不是就可以。这个方法引用了。我就把他们给干掉了。嗯,怎么写呢,我就音,我就冒号,冒号我就萨了。瞎了。哎,我这是不是少括号啊。哎,是不是就搞定了。啊,这也可以是吧,来走起一下。嗯,看这不就还是55。诶,所以为什么我们讲说这个诶死这一篇呢,相当于是真正的把函数是这样的这种操作呢,引入到我们Java中的一个体现了,就是因为呢,你看在调用的时候呢,我们都需要填一些函数式接口,而我们这块呢,都可以使用拉曼表示使用方法应用啊找找感觉。
70:12
啊,其实我现在这个成就感就特别强烈哈,诶强烈在哪儿呢?就是大家呢这块特别懵,然后我这块呢,写的就特别爽啊,这种落差呢,会感觉到极大的虚荣心的满足是吧。呃,大家以后在公司呢,也会是有这种感觉哈,呃,就像咱们一开始讲这个,呃,拉姆达表达式的时候啊,我在一开始的时候呢,这块不给大家呢,呃,列了一个这样的一个。一个一个图一个截图啊这呢,就是前段时间呢,一个同学跟我聊了点是吧。玩的越溜的觉得越厉害啊,你看不看不懂的,人家都瞧不起你是吧?哎,所以自己呢多写写啊就可以了,哎这呢,不就是咱们说的这样一个写法吗。这呢就是他直接粘给我的一个代码。哎,看着是不是有点酸爽是吧,当大家呢,真正自己回去写的时候呢,你发现呢,真的是好方便呀,哎,就是这样一种感觉。
71:04
以前的时候呢,咱们说这个,呃,拉曼表是和这个方法营啊,这个孙雷篇呢,说为了方便大家能够看懂咱们相关的框架的源码啊,建议大家呢去学习一下,呃现在呢,不光是建议大家通过这个角度去学习了,除了这个底层框架呢,他们做了一个呃相关的一个调整之外呢,以后咱们写代码也确实会这样写。啊,所以呢,需要大家掌握啊。好,那下边这个呢,我们看一下这个叫reduce还是它啊,它没有这个种子了。这个我们做什么事呢?说呢,计算一下公司当中所有员工的工资啊,他的一个总和。诶,所以这块呢,大家你看啊,首先呢,咱们这里边儿呢,是一个集合,针对的都是employee。哎,都是员工是吧?哎,我们首先呢,需要做一个映射,这呢咱们对应的是不是叫map呀,那映射完以后呢,这块呢,是不是都是各自的员工的这个salary啊。诶把他们的工资呢都找到,通过员工映射到他们的工资,然后呢,咱们再去做一个叫reduce。
72:06
Reduce完以后呢,我们是不是把它们累加起来就得到一个工资就行,诶所以这块你看我们先映射后归约啊,Map加reduce啊,Map reduce啊,这个对应的这个结构后边呢,大数据的同学呢,要学一个,呃,技术是就要map啊,先映射后归啊,这块呢去体会一下啊。好,那咱们就开始来写,首先呢,针对于咱们叫employee data.get employees是吧?诶,这不就得到我们具体的这个员工了吗?好,得到我们这个,呃,员工构成的一个集合了,首先呢,调一下STEM方法,得到一个STEM的实例,点调这个先别reduce了,是不是先map映射一下啊,左边呢是员工。啊,右边的话呢,通过员工get他的salary是不是就得到他们的工资了嘛,然后呢,再去做这个reduce这个行为,做这个映射了,映射诶做这个规约了啊这个规约的话呢,还是脑海当中浮现出来,咱们也看过了啊这哥们儿呢,他是集成于那个by function的两个参数呗。
73:05
啊,一个呢叫SALARY1,一个叫ARY2对吧,然后呢,咱们给他呢,诶指定一下这哥俩呢,加一下啊,你看这个double里边有没有这个方法啊,有是吧,你把这个361。哎,然后呢,SALARY2是不是就写里边啊。然后呢,打印一下完事啊。写完了。啊,写完了啊,这个稍微的有点长。啊,体会一下,呃,先得到我们的工资,然后呢,再给它们合在一起。啊,来,走起一下。哎,总共的这个工资呢,是这么多啊,这呢也是个optional是吧,你再调下盖的方法也行啊,呃,那这块呢,我们再复制一份,知道我要干什么了吧。诶是不是这个位置呢,咱们给他就直接的给删掉了呀,诶我们就来一个double冒号,冒号sum一下,诶是不是也行。很少括号了啊。
74:01
哎,就可以了,哎,我们再给他跑一下。是不是还是这个数,哎,所以这块呢,我们又实现了一个啊拉曼达表达式,哎,替换为方法应用。啊,找找感觉啊。这个呢,就学完了。嗯,过了啊,然后接着的话呢,咱们看一下最后这一波啊,这个呢叫收集。收集啊。这呢也是这个终止操作了,收集什么呢?注意看啊,咱们前边这块啊,你比如我做了一顿这个映射呀,或者我们讲这个中间操作的时候呢,做了一些这个过滤行为呀。是吧,哎,一开始的这个过滤行为啊,包括咱们讲这个排序的时候呢,做了一个排序啊,最后你发现呢,你一顿排完之后,本身这个数组还是原来的一个顺序。是吧,那不行。啊,或者换句话说,你比如说我们针对这个数组的,我想找到大于30的数据,相当于做个过滤了啊过滤完以后呢,我希望你把这个结果呢,给我固定下来。啊,因为你原有的这个数组并没有产生影响,那你给我存起来呀,啊,这个时候呢,我们就要用到最后这个操作了,就叫做收集的意思了。
75:08
啊,叫做收集啊,你比如说咱们想查找工资大于6000的员工,查完以后的话呢,诶本身我们这个集合没有产生影响,我希望你给我存起来是吧,这时候你就返回一个list或者set就行,我们就调这个结构就行,需要呢传一个叫collector啊。看一下我们这个课件。找到啊,咱们这里边儿提到了一个终止操作。这个收集是吧,好,这里边儿呢,需要传一个collector啊,这个collector的话呢,还是一个接口啊,那这个怎么弄呢?这块注意啊,有一个类,这个类呢叫collectors加了S了,然后这哥们的话呢,里边有很多的静态方法。哎,我们调它这里边儿的这些静态方法,那就能够返回具体的这个collector了。啊,就是这样的一个思路,其实比较简单啊,咱们直接来写啊,呃,这呢,咱们还是先啊这个我写到这儿吧。
76:01
哎,通过我们这个employee data.get employees先得到咱们这样一个集合。这没问题了是吧?好,拿着我们这个集合点先调stream操作,是不就得到stream了吗?然后下边这块呢,查找工资大于6000的员工,这不就是一个典型的filter吧。这是员工,然后呢,他点get salary要求呢,大于6000,诶,这不就搞定了吗?呃,然后呢,这个结果呢,注意咱们现在呢,不是简单的想去便利一下了,我希望呢,你给我固定下来,我呢就调一个叫collect。掉它了是吧,然后这里边儿的话呢,咱们去调这个叫collectors。哎,调它,哎,那你想转化成是一个list还是个set呢?就根据实际需求了啊,比如咱们想转换成是一个list,哎,我就调这个方法。叫to list。来这块呢,我们来一个alt加回车。但你发现呢,此时你看返回的是不是就是一个list了。哎,由这个employee构成的一个例子了,行,那么这个例子呢,咱们去遍历一下。
77:02
哎,这个咱们刚才不是说了,有个这样的一个for each的一个操作吧。啊,是什么out。啊,那就这样写来,走起。那么这时呢,我们反馈这个结果里边呢,工资都是大于6000的。看看没有问题,注意这时候呢,我们得到的这个啊,就是你过滤以后的这个数据了,如果呢,你再去便利一下咱们啊,我再复制一份啊历史的话。这是不是就原来的我们这个数组是吧,他那里边这个数据呢,还是最初的那八条。啊,没有产生任何的影响,看没问题是吧,诶就是你过滤呀,或者你规约呀,映射呀,等等你各种各样的数据啊,然后呢,你要是想这个这个固定下来,你就调我们这个就行了啊。呃,你要想获取的是一个set的话呢,你这块就to set就行。然后呢,我们看下边这个,那呢,按照员工的年龄进行排序啊,返回到一个新的list当中,嗯,没问题啊,诶首先针对list子点我们调了一个STEM这个操作,这呢是先得到STEM,然后呢,咱们是不是要so排序了?
78:09
排序呢,由于咱们这个呃,Employee呢,本身呢,也没有去实现这个自然排序了,所以这块我们得定制了是吧。啊定制啊定制呢,咱们这里边儿注意传的是compor里边这个compare方法俩参数啊,一个叫一,一个叫一二。咱要干啥呢?按照年龄进行排序,OK啊,1.geth啊,减去一二.get age是不是这样就可以了?嗯,排完序以后呢,返回一个新的list,那咱们就来一个呗。啊,这块我们来一个叫a collectors啊,点to list诶这不就搞定了吗。啊,这个我们叫例二吧。好,例二点,我们再来一个叫for each。所以大家你看我们有了这个拉姆达表达式和API以后呢,你看这个代码写起来呢,一行就可以做很多的这个操作了呀。非常的方便啊。
79:02
嗯,这个咱们多一个换行是吧,在这写一下啊。最后这诶此时的话呢,我们是按照这个age来排的,你看没问题程序的,而且呢,咱们把它固定到一个例当中了啊,你可以拿着例呢,继续呢,做其他的一些操作啊没问题行这儿呢,我们就说完了,呃,针对于咱们讲的叫诶stream的这个叫终止操作。啊,结合着咱们讲的这几个操作呢,咱也把这几个事儿呢,其实也都相应的就说清楚了。啊,大家呢,体会一下这儿呢,就是咱们关于STEM讲解的这样的一些细节了。这是G,当我们讲的在G又增加了一些这个的这块,我就不刻意的去了,然也可以我们边的试代码后边的一个练习题,这个练习题呢,我也不刻意的来讲了,对应的这个答案呢,也都给大家了,你也可以呢,自己来去写一写,找找这个感觉啊,OK,那么关于GT8中咱们讲的两个主要的这个新特性,一个呢叫拉姆达表达,一个呢叫string。
80:08
啊,咱们就讲完了这个API里边呢,就体现了拉表示和方法引用的一系列的这个使用。啊,主要呢,还是大家多去写一写,找找感觉才行啊。
我来说两句