当前位置: 首页 > news >正文

江宁网站建设要多少钱网站想更换服务器怎么做

江宁网站建设要多少钱,网站想更换服务器怎么做,增城哪家网站建设好,网站基础建设英文翻译java-Stream原理及相关操作详解 Stream流前言Stream流原理介绍Stream-Api常用方法介绍filter()map()flatMappeekreducemax、minfindAny、 findFirstallMatch、anyMatch、noneMatchsortedcount Stream流前言 Java8特性主要是Stream流以及函数式接口的出现#xff1b;本片文章主… java-Stream原理及相关操作详解 Stream流前言Stream流原理介绍Stream-Api常用方法介绍filter()map()flatMappeekreducemax、minfindAny、 findFirstallMatch、anyMatch、noneMatchsortedcount Stream流前言 Java8特性主要是Stream流以及函数式接口的出现本片文章主要对StreamApi中的常用方法进行讲解再学习Stream流之前个人建议需要对函数式接口要有充分理解并能熟练掌握对于函数式编程的学习大家可以参考java 函数式编程Function、Supplier、Predicate、Consumer 本片文章主要讲解流相关的操作以及部分原理介绍; Stream流原理介绍 Stream流本质上是一个执行计算的过程将流当中的中间操作组成一个流管道的形式流管道由源可能是数组集合生成器函数I / O通道等零个或多个中间操作 将流转换为另一个流如filter(Predicate) 组成以及终端操作 产生结果或副作用例如count()、forEach(Consumer) 、collect(?); 对于collect()方法来讲是Stream的重中之重collect()方法的实现依赖于Collector对于流的终端收集操作(Collector)会放在后续进行讲解 流本身是由三个部分组成分别是源、中间操作、终止操作大家先看个例子 int sum widgets.stream().filter(w - w.getColor() RED).mapToInt(w - w.getWeight()).sum();widgets认为是一个集合本身的引用通过widgets.stream()则创建了一个源中间的filter()和mapToInt() 操作是流的中间操作过程sum是流的一个终端终止操作 大家再来观察一下stream()方法 default StreamE stream() {return StreamSupport.stream(spliterator(), false);}public static T StreamT stream(SpliteratorT spliterator, boolean parallel) {Objects.requireNonNull(spliterator);return new ReferencePipeline.Head(spliterator,StreamOpFlag.fromCharacteristics(spliterator),parallel);}stream() 是 Collection 中的 default 方法实际上调用的是StreamSupport.stream() 方法返回的是 ReferencePipeline.Head的实例ReferencePipeline表示的是流阶段的中间阶段ReferencePipeline.Head表示流的源阶段一个流的只会创建一次源而流的中间操作可以没有或者多个ReferencePipeline.Head 的构造函数传递是 ArrayList 中实现的 spliterator 。常用的集合都实现了 Spliterator 接口以支持 Stream。可以这样理解Spliterator 定义了数据集合流入流水线的方式。 接下来将对Stream的构造方法也就是流的的创建过程以及中间操作阶段的具体实现进行分析来进一步理解流的创建以及流是怎么将每一个中间阶段链接起来并且怎么将每一个阶段的输出通知给下游流 我们先分析stream()方法的最终实现其实是AbstractPipeline而ReferencePipeline继承了AbstractPipeline AbstractPipeline(Spliterator? source,int sourceFlags, boolean parallel) {//表示上一个阶段如果这是源阶段也就是流创建的阶段并没有上游所以这里为null。this.previousStage null;//流管道中的源拆分器实际行为是和sourceSupplier配合将集合中的元素驶向流this.sourceSpliterator source;//流管道的源阶段this.sourceStage this;// 此管道对象表示的中间操作的操作标志this.sourceOrOpFlags sourceFlags StreamOpFlag.STREAM_MASK;// The following is an optimization of:// StreamOpFlag.combineOpFlags(sourceOrOpFlags, StreamOpFlag.INITIAL_OPS_VALUE);//源和所有操作的组合源标志和操作标志直到此流水线对象表示的操作为止包括该流水线对象所代表的操作。 在管道准备进行评估时有效。this.combinedFlags (~(sourceOrOpFlags 1)) StreamOpFlag.INITIAL_OPS_VALUE;//如果是顺序的则此管道对象与流源之间的中间操作数如果是并行的则为先前有状态的中间操作数。 在管道准备进行评估时有效this.depth 0;//表示并行还是串行流this.parallel parallel;}对于stream()的构造方法我认为previousStage 、sourceStage 、depth 三个属性即可能更快捷的去了解流 构造方法执行完成之后流的创建也完成了。创建了源 previousStage 并没有上一个阶段赋予nullsourceStage 原阶段就是当前创建的流对象depth 为0我们目前并没有执行下游流的操作 好了~到目前为止流的创建阶段也就完成了我们再看看下游流是怎么创建的呢拿filter()举例 Overridepublic final StreamP_OUT filter(Predicate? super P_OUT predicate) {Objects.requireNonNull(predicate);// 返回一个匿名无状态操作的管道return new StatelessOpP_OUT, P_OUT(this, StreamShape.REFERENCE,StreamOpFlag.NOT_SIZED) {Override// 下游生产线所需要的回调接口SinkP_OUT opWrapSink(int flags, SinkP_OUT sink) {return new Sink.ChainedReferenceP_OUT, P_OUT(sink) {Overridepublic void begin(long size) {downstream.begin(-1);}// 真正执行操作的方法依靠ChainedReference内置ReferencePipeline引用下游的回调Overridepublic void accept(P_OUT u) {// 只有满足条件的元素才能被下游执行if (predicate.test(u))downstream.accept(u);}};}};}StatelessOp是非常重要的定义了流中无状态操作的属性我这里直接点击到了StatelessOp中具体的构造方法大家再看看一下 /** * previousStage入参表示流对象我们上步骤创建好的流对象 */AbstractPipeline(AbstractPipeline?, E_IN, ? previousStage, int opFlags) {if (previousStage.linkedOrConsumed)throw new IllegalStateException(MSG_STREAM_LINKED);// 表示如果该流管道被消费或者链接则为true上面我们创建了stream()流调用filter方法则表示我们将filter这个阶段已经连接到流previousStage.linkedOrConsumed true;// 流管道的下一个阶段上步骤创建好的流对象下一个对象就是当前对象previousStage.nextStage this;// 此时该流管道中的上一个阶段便是源阶段this.previousStage previousStage;this.sourceOrOpFlags opFlags StreamOpFlag.OP_MASK;this.combinedFlags StreamOpFlag.combineOpFlags(opFlags, previousStage.combinedFlags);// 源阶段只有一个仍然是previousStage.sourceStage;this.sourceStage previousStage.sourceStage;if (opIsStateful())sourceStage.sourceAnyStateful true;// 新增了一个filter操作深度便1this.depth previousStage.depth 1;}在和源阶段的构造方法和下游流创建的构造方法拿出来对比会发现 previousStage.linkedOrConsumed true表示上面我们创建了stream()流调用filter方法则表示我们将filter这个阶段已经连接到流previousStage上一个阶段 对于源的创建来讲没有上一个阶段该属性为null对于下游流来讲上一个阶段就是原阶段linkedOrConsumed 是否消费或链接流创建阶段没有被链接或者消费默认为fasle创建下游流之后被链接上之后为truepreviousStage.nextStage上游流的下个阶段可以理解为源的下一个阶段便是filterdepth 源阶段没有任何中间操作未创建下游流depth 0创建链接之后便1 其实发现previousStage.nextStage this previousStage.linkedOrConsumed this; 通过连接上游流和指向下游流发现流的特性是很像一个双向链表 到目前为止流的创建源阶段以及中间阶段就结束了接下来我们再看一下ReferencePipeline.Head 代表流的源看看数据是怎么走向的呢我们来观察一下ReferencePipeline.Head类 /*** Source stage of a ReferencePipeline.** param E_IN type of elements in the upstream source * param E_OUT type of elements in produced by this stage* since 1.8*/static class HeadE_IN, E_OUT extends ReferencePipelineE_IN, E_OUT {//方法目前已经省略便于观看} 其中有两个泛型参数E_IN、E_OUT,显而易见一个表示进一个表示出E_IN表示的是上游源的元素的类型E_OUT表示的是当前阶段所生成的元素类型 比如我们使用steam: stream().map().filter()… 对于map()阶段来说E_IN则是stream生成的源(Spliterator)E_OUT表示map()处理完之后生成的元素这个元素可能是对象、集合等等。 对于filter()来说 filter()的输入元素就是map()所输出的元素filter()的输出元素则会作为下一个中间动作的输入元素。。。。 流的创建以及数据流向已经介绍完了接下来我们简单介绍流的每一个阶段是怎么进行通知的Sink Sink 这个接口它继承自 Consumer 接口又定义了begin()、end()、cancellationRequested() 方法。Sink 直译过来是水槽如果把数据流比作水那水槽就是水会流过的地方。begin() 用于通知水槽的水要过来了里面会做一些准备工作同样 end() 是做一些收尾工作。cancellationRequested() 是原来判断是不是可以停下来了。Consumer 里的accept() 是消费数据的地方。 每一个 Sink 都有自己的职责但具体表现各有不同。无状态操作的 Sink 接收到通知或者数据处理完了会马上通知自己的 下游。有状态操作的 Sink 则像有一个缓冲区一样它会等要处理的数据处理完了才开始通知下游并将自己处理的结果传递给下游。例如 sorted() 就是一个有状态的操作一般会有一个属于自己的容器用来记录处自己理过的数据的状态。sorted() 是在执行 begin 的时候初始化这个容器在执行 accept 的时候把数据放到容器中最后在执行 end 方法时才正在开始排序。排序之后再将数据采用同样的方式依次传递给下游节点。最后数据流到终止节点终止节点将数据收集起来就结束了。 好了~ ~ 流我们有了一个基础理念、并掌握函数式接口之后我们再来回顾一下Stream中常用方法~~~ Stream-Api常用方法介绍 filter() StreamT filter(Predicate? super T predicate);在对Api讲解时将不再对流的原理进行介绍只关注方法本身的入参出参以及使用 可以看到filter入参是Predicate接受一个参数不返回值 出参仍返回一个Stream方法本身返回由此流中满足给定的Predicate行为后元素组成的流 举个例子集合中有四个元素分别是字符类型supplier, “function”, “predicate”, “consumer”需要将符合条件的元素捞取出来其中符合元素的条件根据业务可调整当前例子是将元素长度8的元素过滤出来。。 Testvoid stream(){ListString list Arrays.asList(supplier, function, predicate, consumer);list.stream().filter(item - item.length() 8).forEach(System.out::println);}打印结果为supplier function consumer结果中predicate元素长度等于9 不满足Predicate行为map() R StreamR map(Function? super T, ? extends R mapper);返回一个流包括将给定函数应用到该流元素的结果。 入参是一个Function(接受一个参数并返回值)出参是Stream 对于map()方法的使用我们需要将集合中的元素进行处理处理完之后并返回新的结果时便可使用map 举个例子 Testvoid stream(){ListString list Arrays.asList(supplier, function, predicate, consumer);//将list中每一个元素末尾加“~~”list.stream().map(item - item ~~).forEach(System.out::println);}结果打印supplier~~ function~~ predicate~~ consumer~~flatMap R StreamR flatMap(Function? super T, ? extends Stream? extends R mapper);将集合中的每一个元素铺开汇聚成新结果以Stream的形式返回 举个例子有两个集合list1、list2 铺开形成一个list Testvoid stream(){// 有两个集合list1、list2需要两个集合中的元素长度等于10的元素收集起来并返回新的集合ListString list1 Arrays.asList(supplier1, function1, predicate1, consumer1);ListString list2 Arrays.asList(supplier2, function2, predicate2, consumer2);ListListString list Arrays.asList(list1, list2);ListString collect list.stream().flatMap(Collection::stream).filter(item - item.length() 10).collect(Collectors.toList());collect.forEach(System.out::println);}输出结果predicate1 predicate2 这样使用起来大家觉得可能用处比较少不属于常用方法但对于oracle来讲对于批量查询如果数据过多会报错需要对数据进行分片分片之后在进行查询 写一个方法大家应该就理解了 /*** param list string的列表根据这个去数据库查* param function 具体的查询方法* param T 返回的list的对象* return 返回数据库查出的具体方法*/public static T ListT partitionThousandGet(ListString list, FunctionListString, ListT function) {return Lists.partition(list, 1000).stream().map(function).flatMap(Collection::stream).collect(Collectors.toList());}其中使用flatMap便可执行分片查询功能在function参数中传入指定的dao层方法即可 peek StreamT peek(Consumer? super T action);peek的意思是偷看入参是Consumer 返回一个Stream返回由该流的元素组成的流并在所提供的流中执行所提供的每个元素上的动作 举一个例子 学生类有名字和分数两个属性 Data public class Student {private String name;private int score; }Test void stream(){Student student1 new Student(zhangsan, 21);Student student2 new Student(lisi, 82);Student student3 new Student(wangwu, 32);// 分别有三个学生需要将lisi的分数改为100分ListStudent list Arrays.asList(student1, student3, student2);list.stream().peek(item - {if (item.getName().equals(lisi)) {item.setScore(100);}}).forEach(System.out::println); } 打印结果为 Student(namezhangsan, score21) Student(namewangwu, score32) Student(namelisi, score100)reduce /**T identity输入元素BinaryOperatorT accumulator 累加器接受两个相同结果的入参返回一个值BinaryOperatorU combiner 合成器在使用并行流时使用 */ T reduce(T identity, BinaryOperatorT accumulator);OptionalT reduce(BinaryOperatorT accumulator);U U reduce(U identity,BiFunctionU, ? super T, U accumulator,BinaryOperatorU combiner);reduce本身时汇聚的一个过程可以将目标元素通过累加器合成最终目标结果元素reduce 操作可以实现从Stream中生成一个值其生成的值不是随意的而是根据指定的计算模型。比如之前提到count、min和max方法因为常用而被纳入标准库中。事实上这些方法都是reduce操作。 举个例子 学生类有名字和分数两个属性Datapublic class Student {private String name;private int score;}Testvoid stream(){Student student1 new Student(zhangsan, 21);Student student2 new Student(lisi, 82);Student student3 new Student(wangwu, 32);//需要计算学生分数总和ListStudent list Arrays.asList(student1, student3, student2);int sum list.stream().mapToInt(Student::getScore).reduce(Integer::sum).getAsInt();System.out.println(sum);}max、min OptionalT max(Comparator? super T comparator);OptionalT min(Comparator? super T comparator);两个方法入参都是Comparator出参是Optional对象返回流中最大或者最小的元素 举个例子 Testvoid stream(){ListString list Arrays.asList(supplier, function, predicate, consumer);//获取流中最大的元素String maxString list.stream().max(String::compareToIgnoreCase).get();System.out.println(maxString);}打印supplierfindAny、 findFirst OptionalT findAny();OptionalT findFirst();findFirst(): findFirst()方法返回流中的第一个元素根据流的顺序。它在并行流操作中的行为更可预测通常会返回流的第一个元素。如果流为空则返回一个空的Optional对象。findAny(): findAny()方法返回流中的任意一个元素。它对于并行流操作提供了更好的性能因为它可以在多个线程中并行地搜索元素。不同的运行时环境可能会对元素的选择有所不同。如果流为空则返回一个空的Optional对象。 当流具有确定顺序的情况下例如使用List创建的流findFirst()和findAny()通常返回相同的结果。但是在并行流操作中由于并行执行的特性findAny()可能更适合并行化操作而且在某些情况下可能具有更好的性能。 举个例子 Testvoid stream(){//对于串行流来讲有序集合两个方法返回的都是同一个元素ListString list Arrays.asList(supplier, function, predicate, consumer);String string1 list.stream().findFirst().get();String string2 list.stream().findAny().get();System.out.println(string1 -- string2);}输出supplier--supplier 但是对于并行流来讲findAny会随机返回一个元素 Testvoid stream(){ListString list Arrays.asList(supplier, function, predicate, consumer);String string1 list.parallelStream().findFirst().get();String string2 list.parallelStream().findAny().get();System.out.println(string1 -- string2);}打印supplier--predicate allMatch、anyMatch、noneMatch boolean allMatch(Predicate? super T predicate); boolean anyMatch(Predicate? super T predicate); boolean noneMatch(Predicate? super T predicate);三个方法都是接受一个Predicate参数返回boolean值三个操作都是Stream中的终止操作 allMatch 用于检查流中所有元素是否满足判断条件 如果都满足返回true 其中有一个不满足返回falseanyMatch用于检查流中至少有一个元素满足判断条件,当流中至少有一个元素满足时返回ture否则false验证流中元素没有一个满足条件时返回true 我们举个例子来说明 Testvoid stream(){ListString list Arrays.asList(supplier, function, predicate, consumer);String str supplier;boolean anyMatchResult list.stream().anyMatch(item - item.equals(str));boolean allMatchResult list.stream().allMatch(item - item.equals(str));boolean noneMatchResult list.stream().noneMatch(item - item.equals(str));System.out.println(anyMatchResult结果 anyMatchResult allMatchResult结果 allMatchResult noneMatchResult结果 noneMatchResult);}运行结果为anyMatchResult结果:true allMatchResult结果:false noneMatchResult结果:false 我们可以看到对于anyMatch方法 集合中有一个元素等于我们定义的字符串supplier条件成立返回true对于allMatch并不是所有元素都等于我们定义的字符串supplier条件不成立返回false对于noneMatch来讲并不是所有元素都不符合条件返回false sorted StreamT sorted();StreamT sorted(Comparator? super T comparator);sorted()将元素从小到大排序 Testvoid stream(){ListString list Arrays.asList(supplier, function, predicate, consumer);list.stream().sorted().forEach(System.out::println);}输出 consumerfunctionpredicatesuppliersorted(Comparator? super T comparator) 比较器自定义排序 Testvoid stream(){//根据字符串长度进行排序ListString list Arrays.asList(supplier, function, predicate, consumer);list.stream().sorted(Comparator.comparing(String::length)).forEach(System.out::println);}输出supplierfunctionconsumerpredicatecount 返回流中元素的个数 举个例子 Testvoid stream(){ListString list Arrays.asList(supplier, function, predicate, consumer);long count list.stream().count();System.out.println(count);}打印4
http://www.pierceye.com/news/733121/

相关文章:

  • 卡易售网站建设信息流投放平台
  • 装修设计公司网站有哪些5g国产天天5g天天
  • 网站内容管理校园网站建设报价
  • 哪个网站系统做的好网站设计原则的第三要素
  • 老区建设网站亚马逊市场营销案例分析
  • 固原建设厅官方网站智慧树网站的章节题做不了
  • 网站建设人才logo设计在线
  • 在网站上做广告教育网站平面设计
  • 中文html网站模板下载做健康类网站怎么备案
  • 何为响应式网站建设公司网站的步骤
  • 网站有哪些分类网游开发公司
  • 织梦网站做瀑布流方便建设网站平台的建议
  • 网站建设实验报告阿里云搭建个人博客wordpress
  • 深圳市福田建设局网站文创产品设计就业前景
  • 龙岗建设网站制作做网站的目的是什么
  • 网站公司做的比较好网站建设业务饱和了吗
  • 做网站做电脑版还是手机版好可以访问国外网站的dns
  • 网站制作素材图片英文站 wordpress seo优化
  • 现在ui做的比较好的网站徐州经济技术开发区
  • 网站设计公司网帐号售卖网站建设
  • 信阳建设网站哪家好wordpress 文章评价插件
  • 网校网站模板东莞网站关键字
  • 做游戏的php网站2019做seo网站
  • 做外贸那个网站好免费asp主机网站
  • 网站设计服务要不要交文化事业建设费在线解压zip网站
  • 沈阳关键词自然排名西安百度seo排名软件
  • 徐州网站建设市场分析手工灯笼简单又好看
  • 网站开发学什么语音提供设计的的网站
  • 微站和网站数据同步icp备案查询
  • 诸城网站制作wordpress圆角插件汉化