当前位置: 首页 > 科技观察

Stream的分类、执行过程及各种创建方式

时间:2023-03-13 07:06:32 科技观察

本文为系列文章。上一篇《??Stream案例体验??》通过丰富的案例体验了Stream的便捷。本文主要讲解:Stream的运行过程,结合本文和前面的案例,体验了Stream的创建方法,Stream的运行分类,串行流和并行流的区别。这里通过一个货运案例来讲解Stream的运行过程,通过【代码实现】+【示意图】来讲解清楚Stream计算数据的过程!需求:获取价格大于5000元的运单号。分析:创建运单数据并通过collection的stream方法创建stream,然后通过调用stream对象的filter方法过滤出需要的数据【中间操作】再通过collection的map方法获取需要的数据流对象字段数据【中间操作】通过collect方法将流对象转化为集合,终止流【终止操作】代码实现:运单类可以直接复用《??Stream案例体验??》导入java.math.BigDecimal;导入java.util.*;导入java.util.stream.Collectors;导入java.util.stream.Stream;公共类WaybillMain{privatestaticListwaybills=newArrayList<>();static{//创建数据waybills.add(newWaybill(1L,"Y11111111111",newBigDecimal(1000),"steel",newBigDecimal(200),"Shanghai"));waybills.add(newWaybill(2L,"Y22222222222",newBigDecimal(2000),"Steel",newBigDecimal(300),"郑州"));waybills.add(newWaybill(3L,"Y33333333333",newBigDecimal(3000),"水泥",newBigDecimal(300),"北京"));waybills.add(newWaybill(4L,"Y44444444444",newBigDecimal(4000),"cement",newBigDecimal(400),"广州市"));waybills.add(newWaybill(5L,"Y55555555555",newBigDecimal(5000),"Sand",newBigDecimal(500),"Shanghai"));waybills.add(newWaybill(6L,"Y66666666666",newBigDecimal(6000),"plate",newBigDecimal(500),"深圳"));waybills.add(newWaybill(7L,"Y77777777777",newBigDecimal(7000),"vegetables",newBigDecimal(500),"杭州市"));}publicstaticvoidmain(String[]args){//1.获取运费大于5000的运单号//1)通过集合的stream方法创建流Streamstream=waybills.stream();//2)使用filter方法过滤超过5000个运单的运单StreamfilterWaybill=stream.filter(item->item.getPrice().compareTo(newBigDecimal(5000))==1);//3)获取过滤后的运单编号StreamwayNoStream=filterWaybill.map(Waybill::getWayNo);//4)将流转换为新的集合ListwayNoList=wayNoStream.collect(Collectors.toList());//5)遍历方式NoList.forEach(System.out::println);}}运行过程:Stream操作的分类上一节我们说了Stream操作分为两大类,[中间操作]和[结束操作],这里详细介绍一下无状态:不影响元素的处理bypreviouselements,suchas:filtering,mapping,andconversiontypesStateful:元素只有在得到所有元素后才能继续,比如排序,goHeavynon-short-circuitoperation:必须处理所有元素才能得到结果,如:求最大值,遍历短路操作:当某些元素满足条件时,可以得到最终的结果,如:获取第一个出现的数据流,创建一个流可以用来处理数据如数组、集合、IO资源,分为【串行流】和【并行流】两种。它的创建方法主要分为以下几种:使用Collection[stringStream]下的stream()方法和parallelStream()方法[parallelstream]Listlist=Arrays.asList("a","b","c");//创建一个顺序流Streamstream=list.stream();//创建一个并行流StreamparallelStream=list.parallelStream();使用Arrays中的stream()方法将数组转为流int[]array={1,3,5,6,8};IntStreamstream=Arrays.stream(array);使用Stream中的静态方法:of(),iterate(),generate()对于像iterate、generate这样没有数据长度的流称为“无限流”,需要使用limit()指定流长度。比如generate就是生成数据,生成多少数据?需要用limit来指定Streamstream=Stream.of(1,2,3,4,5,6);//参数1:是起始值//参数2:每个值做什么,然后根据结果进行下一步操作//limit:upto4operationsListiterate=Stream.iterate(1,x->x*3).limit(4).collect(Collectors.toList());System.out.println(iterate);//生成3个随机数Streamlimit=Stream.generate(Math::random).limit(3);limit.forEach(System.out::println);使用BufferedReader.lines()方法将每一行的内容转换成一个流lineStream.forEach(System.out::println);使用Pattern.splitAsStream()方法,字符串分割成流串行流和并行流的区别stream()方法创建的是[串行流],也可以称为[顺序流],主线程依次对流进行操作,而parallelStream()方法创建的是[并行流]溪流]。通过多个线程并行执行流操作,但前提是流中的数据处理没有顺序要求。比如过滤集合中的奇数,两者的处理是不同的:如果流中的数据量足够大,并行流可以加快处理速度。除了直接创建并行流,还可以通过parallel()将顺序流转换为并行流://创建数组Integer[]arr={1,2,3,4,5,6,7,8,9,10};//通过stream转成串行流,再通过Stream对象的parallel方法转成并行流StreamintegerStream=Arrays.stream(arr).parallel();//对于计算,并行流只能对非有序的要求计算生效//mao:Foreachdata*2Listlist=integerStream.map(x->x*2).collect(Collectors.toList());list.forEach(System.out::println);