专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

WebFlux前置知识(三)

  Stream流式API也是JDK8开始引入的API,用过的小伙伴都说爽,没用过的小伙伴则感到一脸懵逼。现在JDK已经到16了,可能很多人还不熟悉Stream流操作,这次趁着讲WebFlux,和大家一起回顾一下Stream流操作。1。Stream流简介
  说到Stream,大家可能很容易想到JavaIO中的各种流操作,名字看起来很像,但这其实是两个完全不同的东西。
  Java8中的Stream不存储数据,它通过函数式编程模式来对集合进行链状流式操作。2。基本玩法
  先来个简单的例子感受下Stream的操作。
  例如我有一个数组,如下:int〔〕arr{1,2,3,4,5,6};
  现在想给这个数组求平均数,如下:doubleasDoubleIntStream。of(arr)。average()。getAsDouble();
  一行代码搞定,首先调用IntStream。of方法获取流对象,然后调用average方法计算平均数,再调用getAsDouble方法获取结果。全程都是方法调用,不用自己写求平均数的逻辑。
  再比如求和,如下:intsumIntStream。of(arr)。sum();
  也是直接调用sum方法即可。
  而且我们还可以在流中对数据进行二次加工,例如给数组中的每个元素先求平方再求和:double〔〕arr{1,2,3,4,5,6};doublesumDoubleStream。of(arr)。map(iMath。pow(i,2))。sum();
  先在Map中对每一个元素求平方,然后再求和。
  这里就能涉及到两个概念:中间操作终止操作
  所谓中间操作,就是中途求平方的操作,所谓终止操作就是最终计算出结果的操作,只要方法的返回值不是一个Stream,那就是终止操作,否则就是中间操作。3。Stream的创建
  获取一个流的方式多种多样,最常见的就是从集合或者数组中获取一个流,当然我们也可以直接自己创建一个流出来。
  一起来看下。集合
  List集合或者Set集合都可以直接搞一个流出来,方式如下:ListStringlistnewArrayList();StreamStrings1list。stream();SetStringsetnewHashSet();StreamStrings2set。stream();
  集合中直接调用stream方法就可以获取到流。数组
  通过数组获取流的方式也很简单,如下:IntStreamstreamArrays。stream(newint〔〕{11,22,33,44,55,66});数字Stream
  也可以直接利用IntStream、LongStream等对象创建一个数字Stream,如下:IntStreams1IntStream。of(1,2,3);DoubleStreams2DoubleStream。of(1,2,3);LongStreams3LongStream。of(1L,2L,3L);自己创建RandomrandomnewRandom();SupplierIntegersupplier()random。nextInt(100);StreamIntegerstreamStream。generate(supplier)。limit(5);
  调用Stream。generate方法可以自己创建一个流,自己创建的时候需要提供一个Supplier,通过调用Supplier中的get方法自动获取到元素。
  无论哪种创建方式,大家需要明白的是,Stream并不会保存数据,它只会对数据进行加工。4。Stream的中间操作
  中间操作可以分为两大类:map或者filter会从输入流中获取每一个元素,并且在输出流中得到一个结果,这些操作没有内部状态,称为无状态操作。reduce、sum、max这些操作都需要内部状态来累计计算结果,所以称为有状态操作。
  分别来看下:
  无状态操作mapmapToXxxflatMapflatMapToXxxfilterpeek
  有状态操作distinctsortedlimitskip
  map
  Stream。map()是Stream中最常用的一个转换方法,可以把一个Stream对象转为另外一个Stream对象。map方法所接收的参数就是一个Function对象,松哥在前面文章中和大家介绍过Function对象了,就是有输入有输出(参见WebFlux前置知识(一)),了解了map的参数,那么map的功能就很明白了,就是对数据进行二次加工。
  举个栗子,例如把一个字符串数组转为数字:String〔〕arr{1,2,3};StreamStrings1Arrays。stream(arr);StreamIntegers2s1。map(iInteger。valueOf(i));
  再比如一个数字流,给所有的元素乘2,如下:IntStream。of(1,2,3)。map(i2i)。forEach(System。out::println);
  最后的forEach就是将元素打印出来。
  JDK中也提供了一些现成的格式转换,如下图:
  这样可以直接将元素转为Double、Long、Obj等类型,例如下面这样:String〔〕arr{1,2,3};StreamStrings1Arrays。stream(arr);s1。mapToLong(iLong。parseLong(i))。forEach(System。out::println);
  flatMap
  flatMap可以把Stream中的每个元素都映射为一个Stream,然后再把这多个Stream合并为一个Stream。
  例如如下代码,返回的Stream中的元素是数组:StreamInteger〔〕sStream。of(newInteger〔〕{1,2,3},newInteger〔〕{4,5,6},newInteger〔〕{7,8,9});s。forEach(System。out::println);
  通过flatMap我们可以将Stream中的元素变为Integer:StreamIntegersStream。of(newInteger〔〕{1,2,3},newInteger〔〕{4,5,6},newInteger〔〕{7,8,9})。flatMap(iArrays。stream(i));s。forEach(System。out::println);
  filter
  filter操作会对一个Stream中的所有元素一一进行判断,不满足条件的就被过滤掉了,剩下的满足条件的元素就构成了一个新的Stream。
  例如要找到数组中所有大于3的元素,如下:IntStream。of(2,3,4,5,6,7)。filter(ii3)。forEach(System。out::println);
  filter方法接收的参数是Predicate接口函数,关于Predicate接口函数,大家可以参考WebFlux前置知识(一))一文。
  peek
  peek的入参是Consumer,没有返回值,因此当我们要对元素内部进行处理时,使用peek是比较合适的,这个时候可以不用map(map的入参是Function,它是有返回值的)。peek方法本身会继续返回流,可以对数据继续进行处理。
  举个简单的数据转换的例子吧(最终返回的数据并不会被转换):IntStream。of(2,3,4,5,6,7)。filter(ii3)。peek(String::valueOf)。forEach(iSystem。out。println(i));
  peek方法的感觉就像数据中途被消费了一次。
  distinct
  这个是去重。由于去重操作需要获取到其他元素的值(比较之后才知道是否重复),所以这个是有状态操作。如下:IntStream。of(2,3,4,3,7,6,2,5,6,7)。distinct()。forEach(System。out::println);
  sorted
  sorted是排序,因为也需要知道其他元素的值,然后才能去重,所以这个也是有状态操作,如下:IntStream。of(2,3,4,3,7,6,2,5,6,7)。distinct()。sorted()。forEach(System。out::println);
  limitskip
  limit和skip配合操作有点像数据库中的分页,skip表示跳过n个元素,limit表示取出n个元素。例如下面这个例子:Arrays。asList(A,B,C,D,E,F)。stream()。skip(2)。limit(3)。forEach(System。out::println);
  这个会跳过A和B,最终打印出CDE。这也是一种有状态操作。5。Stream终止操作
  终止操作就是最终计算出结果的操作,只要方法的返回值不是一个Stream,那就是终止操作,否则就是中间操作。
  终止操作又分为两类:短路操作:不用处理全部元素就可以返回结果。非短路操作:必须处理所有元素才能得到最终结果。
  各自都包含哪些操作,我们分别来看下:
  非短路操作forEachforEachOrderedcollecttoArrayreduceminmaxcount
  短路操作findFirstfindAnyallMatchanyMatchnoneMatch
  forEachforEachOrdered
  forEach和forEachOrdered都是接收一个Consumer类型的参数,完成对参数的消费,不同的是,在并行流中,forEachOrdered会保证执行顺序。
  例如如下一段代码:int〔〕arr{1,2,3,4,5,6,7,8,9};Arrays。stream(arr)。parallel()。forEach(System。out::println);Arrays。stream(arr)。parallel()。forEachOrdered(System。out::println);
  前者打印出来的顺序不一定是123456789,后者一定是。
  collecttoArray
  这两个都是收集器,可以将执行结果转为一个List集合或者一个数组:ListIntegerlistStream。of(1,2,3,4)。filter(pp2)。collect(Collectors。toList());System。out。println(list);
  reduce
  reduce是Stream的一个聚合方法,它可以把一个Stream的所有元素按照聚合函数聚合成一个结果。reduce方法传入的对象是BinaryOperator接口,它定义了一个apply方法,负责把上次累加的结果和本次的元素进行运算,并返回累加的结果。
  举个简单的例子,数组求和,当然可以直接调用sum计算,我们这里也可以调用reduce来实现,如下:OptionalIntegeroptionalStream。of(1,2,3,4)。reduce((i,j)ij);System。out。println(optional。orElse(1));
  reduce的参数是BinaryOperator,这个接收两个参数,第一个参数是之前计算的结果,第二个参数是本次参与计算的元素,两者累加求和。
  再比如给一段话中间加上。,方式如下:OptionalStringsStream。of(wwwjavaboyorg。split())。reduce((i,j)i。j);System。out。println(s。orElse());
  最终执行结果如下:w。w。w。j。a。v。a。b。o。y。o。r。g
  minmaxcount
  这个就比较简单了,就是求最大值最小值,统计总个数,如下表示统计总个数:StreamIntegersStream。of(1,2,3,4);longcounts。count();System。out。println(countcount);
  如下表示统计最小值:StreamIntegersStream。of(1,2,3,4);OptionalIntegermins。min(Comparator。comparingInt(ii));System。out。println(min。get()min。get());
  findFirstfindAny
  这两个就是返回流中的第一个、任意一个元素,findAny要在并行流中测试才有效果,举个栗子:for(inti0;i10;i){OptionalIntegerfirstStream。of(1,2,3,4)。parallel()。findFirst();System。out。println(first。get()first。get());}System。out。println();for(inti0;i10;i){OptionalIntegerfirstStream。of(1,2,3,4)。parallel()。findAny();System。out。println(first。get()first。get());}
  allMatchanyMatchnoneMatch
  allMatch、anyMatch、noneMatch用来判断所有元素、任意元素或者没有元素满足给定的条件。这三个方法的参数都是一个Predicate接口函数。booleanbStream。of(1,2,3,4)。allMatch(ii5);System。out。println(bb);6。并行流
  通常情况下,对Stream的元素进行处理是单线程的,即一个一个元素进行处理。有时候我们希望可以并行处理Stream元素,因为在元素数量非常大的情况,并行处理可以大大加快处理速度。
  把一个普通Stream转换为可以并行处理的Stream非常简单,只需要用parallel方法进行转换:newRandom()。ints()。limit(50)。parallel()。forEach(i{System。out。println(Thread。currentThread()。getName()i);});
  这样数据在后台就是并行打印的。7。收集器
  收集器可以将计算结果重新整理收集到一个集合中,这个集合可以是一个ListSet获取其他,并且还可以在收集的过程中对数据进行处理。
  例如我有一个users集合,里边保存了用户数据,用户有username、age以及gender三个属性,如下代码分别表示:提取出用户对象中的age属性组成新的集合并返回。提取出用户对象中的username属性组成新的集合并返回。提取出用户对象中的gender属性组成新的集合并返回(这里是一个Set集合,所以会自动去重)。ListIntegeragesusers。stream()。map(User::getAge)。collect(Collectors。toList());System。out。println(agesages);ListStringusernamesusers。stream()。map(User::getUsername)。collect(Collectors。toList());System。out。println(usernamesusernames);SetStringgendersusers。stream()。map(User::getGender)。collect(Collectors。toSet());System。out。println(gendersgenders);
  Collectors。toList()最终返回的是ArrayList,Collectors。toSet()最终返回的是HashSet。
  如果我们想返回一个Vector或者TreeSet,也是可以的,如下:ListIntegeragesusers。stream()。map(User::getAge)。collect(Collectors。toList());System。out。println(agesages);ListStringusernamesusers。stream()。map(User::getUsername)。collect(Collectors。toCollection(Vector::new));System。out。println(usernamesusernames);TreeSetStringgendersusers。stream()。map(User::getGender)。collect(Collectors。toCollection(TreeSet::new));System。out。println(gendersgenders);
  也可以获取某一个字段的统计信息:IntSummaryStatisticsageStatisticsusers。stream()。collect(Collectors。summarizingInt(User::getAge));System。out。println(ageStatisticsageStatistics);
  这个统计信息中包含:总和、最小值、平均值以及最大值等:ageStatisticsIntSummaryStatistics{count20,sum1222,min9,average61。100000,max96}
  还可以对数据进行分块,将男女不同性别统计出来:MapBoolean,ListUsermapusers。stream()。collect(Collectors。partitioningBy(uu。getGender()。equals(男)));System。out。println(mapmap);
  也可以按照性别对数据进行分组,如下:MapString,ListUsermap2users。stream()。collect(Collectors。groupingBy(User::getGender));System。out。println(map2map2);
  分组后,Map中的key就是性别;分块后,Map中的key就是truefalse。
  再比如统计男女的人数:MapString,Longmap2users。stream()。collect(Collectors。groupingBy(User::getGender,Collectors。counting()));System。out。println(map2map2);
  好啦,今天我们就先聊这么多~
  原文链接:https:mp。weixin。qq。comscuxnkcfAOLZuxWRmYcnKWg

英雄联盟S赛分组出炉,有人骂MLXG手臭,他表示LPL好签凡是过往,皆为序章。大家好,我是晓默!抽签仪式9月15日晚20点整,LOL世界赛抽签仪式正式开始,由主持人余霜主持,微笑厂长和麻辣香锅三人充当抽签嘉宾,记得Cat957和管泽元担当LGD双杀V3,狼行禁英雄防队友,拿贾克斯惊呆粉丝,猛吹一波凡是过往,终为序章。大家好,我是晓默!入围赛第三天赛果今天LOL入围赛B组的所有战队第一阶段的比赛已经结束了,LPL的四号种子LGD两次击败V3战队,为自己保留了冲击小组赛的希望,英雄联盟揭幕战,双方辅助频繁失误,Zhuo难帮TES复仇SN凡是过往,皆为序章。大家好,我是晓默。自从S10全球总决赛结束之后,等待了近两个月的时间,我们终于迎来了改版后的S11赛季,虽然中间有德杯和全明星赛为各位召唤师解闷,但是对于LOL英雄联盟手游虚空斗法和帝国剑士被卡棋怎么办?快换这套阵容山鸟与鱼不相知,陌路相逢是故人。大家好,我是等待关注的晓默!金铲铲之战目前英雄联盟手游还在内测中,很多lol迷迫不及待的下载了模拟器,想体验这个手机版的英雄联盟。而在8月26日,腾FPX30零封RNG,别人取胜是依靠实力,他却靠版本拿冠军图文创作打卡挑战活动英雄联盟春季季后赛山鸟与鱼不相知,陌路相逢是故人。大家好,我是等待关注的晓默。FPX对阵RNGLPL春季赛四强赛第一场,本以为通过闯关晋级而来的FPX在与JDGGimgoon回归FPX组成冠军完全体,Smlz拿AP大嘴也不行,季后赛稳了凤凰涅槃,浴火重生。大家好,我是晓默!FPX战队虽然在上个赛季获得了S赛冠军,成为了第二支拥有冠军皮肤的LPL战队,但是给我们的感觉好像并没有太多的重视,也许是因为受到疫情的冲击,RW零胜八负无缘季后赛,魏延之后LPL再无侠队,那真的是假赛?凤凰涅槃,浴火重生。大家好,我是晓默!LOL这款游戏自从S2赛季登陆国服之后,瞬间风靡国内,至今已有近九个年头。这么火爆的游戏不仅仅源于他炫彩的游戏画面,更在于游戏之中,队友之间的WE拿第八胜,黑科技人马上场,Jiumeng从未让人失望,季后赛稳了凤凰涅槃,浴火重生。大家好,我是晓默!今年LPL夏季赛强队频出,与往年大相径庭,越是到赛季末,局势越不明朗!除了已经九胜和获得八败的几支队伍外,每一个队伍都表现出能够拿到季后赛门票IG与RNG决胜局,精彩程度比春晚,纳尔一拍五,谁还说Puff是盗版凤凰涅槃,浴火重生。大家好,我是晓默!IG战队在首局劣势翻盘以及第二局在前期完全崩盘的局面下,最终还是没有实现不加班的愿望,把比赛拖入了第三局!在经历了跌宕起伏的前两局之后,两队又NS暗黑破坏神2玩家福利来啦!奇游已支持热点加速暗黑破坏神2重制版已经登录PC战网和主机平台,其中NS侧的加速需求极强,除了战网绑定平台账号需要用到加速外,游戏的下载和联机都需要加速支持,否则无法完成验证玩游戏,单机都不可以哟针看了LPL出征队伍大名单,才发现冲进世界赛原因,LGD尴尬了凡是过往,皆为序章。大家好,我是晓默!达到王者段位的职业选手LOL世界赛分组抽签结果早已出炉,如今,各支队伍都在忙忙碌碌的开始进行训练,虽然其他赛区的队伍在峡谷之巅被绝活哥教育,吃
三国杀用间篇专属锦囊哪张最妙?谁才是新晋锦囊一哥哈喽!各位好呀,我是淮竹,持续为你带来三国杀移动版最新资讯和趣味玩法喜欢的话希望你能陪伴下去哦最近风风火火的用间篇想必肯定圈出了不少杀友吧,全新的玩法和锦囊让很多玩家上头,每天5次三国杀听说新来了个武将比界徐盛还阴间?曹丕忍不禁哈哈大笑不知道各位有没有发现,三国杀武将越出越多,但出的武将一个比一个阴间,越来越无脑,从之前的马钧贾逵到后来的界徐盛王元姬,简直就是阴间大乱斗,比的就是谁更赖,好像跟技术关系不大了。然而三国杀严峻到底怎么玩,严格递增和递减?策划都是数学家?如果玩的久的杀友肯定有这么一种感觉,不管武将的技能描述再长,充其量也就是文字游戏,只要我看懂了,那么这个武将我就还能搞懂,但是如果你玩数学的话,我玩个游戏还要算术是不是有点过分了?三国杀没有限定技却硬被针对成限定技,他为何如此招人恨?三国杀移动版这把可以输,大师必须死这句话不知道是多少玩家军争场的真实写照,现在开一把三国杀看见大师无脑盲就完事了,明明只是个3血平平无极的东吴武将,为何如此招人恨呢?这背后究竟是道三国杀有哪些限定技用完就是废物的武将呢?三国杀移动版哈喽!各位好呀,我是淮竹,持续为你带来三国杀移动版最新资讯和趣味玩法喜欢的话希望你能陪伴下去哦三国杀武将的技能有很多,而其中又有普通技锁定技限定技,而其中又属限定技最为三国杀究竟有多少个能改判的武将?哈喽!各位好呀,我是淮竹,持续为你带来三国杀移动版最新资讯和趣味玩法喜欢的话希望你能陪伴下去哦说起三国杀能改判的武将,大家肯定第一时间灵魂一颤然后脱口而出就是张角司马懿,作为经典场三国杀为什么国战武器不能加入军争场?一定不能加,否则乱杀三国杀移动版如果你是常玩三国杀移动版军争场的老玩家的话,你就会发现军争很多年都没有添加装备和锦囊了,即便有新出的装备也只会出现在其他场次中,例如移动版大受好评的用间篇,有新装备女装三国杀第一武器究竟是谁?为什么一定不是诸葛连弩哈喽!各位好呀,我是淮竹,持续为你带来三国杀移动版最新资讯和趣味玩法喜欢的话希望你能陪伴下去哦三国杀移动版的武器只有那么几把,玩的多的小伙伴肯定对它们都已经烂熟于心了,自然对它们的三国杀给蔡文姬加个挑衅能否成为三国第一攻防武将?三国杀移动版相信大家在玩游戏的过程中肯定会听到不动白三个字,甚至有的玩家在斗地主中深受其害,正所谓不怕地主选麴义祢衡,就怕队友郭嘉曹冲,这背后的原因究竟是什么?其实就是他们的技能很三国杀谁是三国第一装备管理大师?三国杀移动版哈喽!各位好呀,我是淮竹,持续为你带来三国杀移动版最新资讯和趣味玩法喜欢的话希望你能陪伴下去哦所谓靠山吃山,靠海吃海。每一片不同地方的人们都拥有不同的特质,三国杀也是如三国杀逆向突破?界简雍应该是界武将里最敷衍的一个吧哈喽!各位好呀,我是淮竹,持续为你带来三国杀移动版最新资讯和趣味玩法喜欢的话希望你能陪伴下去哦最近三国杀移动版测试服更新,大家迅速来围观即将上线的界武将,为的就是提前知道强度便于到
友情链接:快好知快生活快百科快传网中准网文好找聚热点快软网