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

营销网站的专业性诊断评价和优化wordpress 搬到本地

营销网站的专业性诊断评价和优化,wordpress 搬到本地,网站制作 wordpress,合肥网站推广Stream流的使用流操作是Java8提供一个重要新特性#xff0c;它允许开发人员以声明性方式处理集合#xff0c;其核心类库主要改进了对集合类的 API和新增Stream操作。Stream类中每一个方法都对应集合上的一种操作。将真正的函数式编程引入到Java中#xff0c;能 让代码更加简…Stream流的使用流操作是Java8提供一个重要新特性它允许开发人员以声明性方式处理集合其核心类库主要改进了对集合类的 API和新增Stream操作。Stream类中每一个方法都对应集合上的一种操作。将真正的函数式编程引入到Java中能 让代码更加简洁极大地简化了集合的处理操作提高了开发的效率和生产力。同时stream不是一种数据结构它只是某种数据源的一个视图数据源可以是一个数组Java容器或I/O channel等。在Stream中的操作每一次都会产生新的流内部不会像普通集合操作一样立刻获取值而是惰性 取值只有等到用户真正需要结果的时候才会执行。并且对于现在调用的方法本身都是一种高层次构件与线程模型无关。因此在并行使用中开发者们无需再去操 心线程和锁了。Stream内部都已经做好了。如果刚接触流操作的话可能会感觉不太舒服。其实理解流操作的话可以对比数据库操作。把流的操作理解为对数据库中 数据的查询操作集合  数据表元素  表中的每条数据属性  每条数据的列流API  sql查询流操作详解Stream流接口中定义了许多对于集合的操作方法总的来说可以分为两大类中间操作和终端操作。中间操作会返回一个流通过这种方式可以将多个中间操作连接起来形成一个调用链从而转换为另外 一个流。除非调用链后存在一个终端操作否则中间操作对流不会进行任何结果处理。终端操作会返回一个具体的结果如boolean、list、integer等。1、筛选对于集合的操作经常性的会涉及到对于集中符合条件的数据筛选Stream中对于数据筛选两个常见的API filter(过滤)、distinct(去重)1.1基于filter()实现数据过该方法会接收一个返回boolean的函数作为参数终返回一个包括所有符合条件元素的流。案例获取所有年龄20岁以下的学生/*** author 我是七月呀* date 2020/12/22*/public class FilterDemo {public static void main(String[] args) {//获取所有年龄20岁以下的学生ArrayList students new ArrayList();students.add(new Student(1,19,张三,M,true));students.add(new Student(1,18,李四,M,false));students.add(new Student(1,21,王五,F,true));students.add(new Student(1,20,赵六,F,false));students.stream().filter(student - student.getAge()20);}}源码解析此处可以看到filter方法接收了Predicate函数式接口。首先判断predicate是否为null如果为null则抛出NullPointerException;构建Stream重写opWrapsink方法。参数flags:下一个sink的标志位供优化使用。参数sink下一个sink通过此参数将sink构造成单链。此时流已经构建好但是因为begin()先执行此时是无法确定流中后续会存在多少元素的所以传递-1代表无法确定。最后调用Pridicate中的test进行条件判断将符合条件数据放入流中。1.2基于distinct实现数据去重/*** author 我是七月呀* date 2020/12/22*/public class DistinctDemo {public static void main(String[] args) {List integers Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);integers.stream().distinct().collect(Collectors.toList());}}源码解析根据其源码我们可以知道在distinct()内部是基于LinkedHashSet对流中数据进行去重并终返回一个新的流。2、切片2.1基于limit()实现数据截取该方法会返回一个不超过给定长度的流案例获取数组的前五位/*** author 我是七月呀* date 2020/12/22*/public class LimitDemo {public static void main(String[] args) {//获取数组的前五位List integers Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);integers.stream().limit(5);}}源码解析对于limit方法的实现它会接收截取的长度如果该值小于0则抛出异常否则会继续向下调用 SliceOps.makeRef()。该方法中this代表当前流skip代表需要跳过元素比方说本来应该有4个元素当跳过元素 值为2会跳过前面两个元素获取后面两个。maxSize代表要截取的长度在makeRef方法中的unorderedSkipLimitSpliterator()中接收了四个参数Spliteratorskip(跳过个数)、limit(截取 个数)、sizeIfKnown(已知流大小)。如果跳过个数小于已知流大小则判断跳过个数是否大于0如果大于则取截取 个数或已知流大小-跳过个数的两者小值否则取已知流大小-跳过个数的结果作为跳过个数。后对集合基于跳过个数和截取个数进行切割。2.2基于skip()实现数据跳过案例从集合第三个开始截取5个数据/*** author 我是七月呀* date 2020/12/22*/public class LimitDemo {public static void main(String[] args) {//从集合第三个开始截取5个数据List integers Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);List collect integers.stream().skip(3).limit(5).collect(Collectors.toList());collect.forEach(integer - System.out.print(integer ));}}结果4 4 5 5 6案例先从集合中截取5个元素然后取后3个/*** author 我是七月呀* date 2020/12/22*/public class LimitDemo {public static void main(String[] args) {//先从集合中截取5个元素然后取后3个List integers Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);List collect integers.stream().limit(5).skip(2).collect(Collectors.toList());collect.forEach(integer - System.out.print(integer ));}}结果3 4 4源码分析在skip方法中接收的n代表的是要跳过的元素个数如果n小于0抛出非法参数异常如果n等于0则返回当前 流。如果n小于0才会调用makeRef()。同时指定limit参数为-1.此时可以发现limit和skip都会进入到该方法中在确定limit值时如果limit0,则获取已知集合大小长度-跳过的长度。最终进行数据切割。3、映射在对集合进行操作的时候我们经常会从某些对象中选择性的提取某些元素的值就像编写sql一样指定获取表 中特定的数据列#指定获取特定列 SELECT name FROM student在Stream API中也提供了类似的方法map()。它接收一个函数作为方法参数这个函数会被应用到集合中每一个 元素上并终将其映射为一个新的元素。案例获取所有学生的姓名并形成一个新的集合/*** author 我是七月呀* date 2020/12/22*/public class MapDemo {public static void main(String[] args) {//获取所有学生的姓名并形成一个新的集合ArrayList students new ArrayList();students.add(new Student(1,19,张三,M,true));students.add(new Student(1,18,李四,M,false));students.add(new Student(1,21,王五,F,true));students.add(new Student(1,20,赵六,F,false));List collect students.stream().map(Student::getName).collect(Collectors.toList());collect.forEach(s - System.out.print(s ));}}结果张三 李四 王五 赵六源码解析内部对Function函数式接口中的apply方法进行实现接收一个对象返回另外一个对象并把这个内容存入当前 流中后返回4、匹配在日常开发中有时还需要判断集合中某些元素是否匹配对应的条件如果有的话在进行后续的操作。在 Stream API中也提供了相关方法供我们进行使用如anyMatch、allMatch等。他们对应的就是和||运算符。4.1基于anyMatch()判断条件至少匹配一个元素anyMatch()主要用于判断流中是否至少存在一个符合条件的元素它会返回一个boolean值并且对于它的操作 一般叫做短路求值案例判断集合中是否有年龄小于20的学生/*** author 我是七月呀* date 2020/12/22*/public class AnyMatchDemo {public static void main(String[] args) {//判断集合中是否有年龄小于20的学生ArrayList students new ArrayList();students.add(new Student(1,19,张三,M,true));students.add(new Student(1,18,李四,M,false));students.add(new Student(1,21,王五,F,true));students.add(new Student(1,20,赵六,F,false));if(students.stream().anyMatch(student - student.getAge() 20)){System.out.println(集合中有年龄小于20的学生);}else {System.out.println(集合中没有年龄小于20的学生);}}}根据上述例子可以看到当流中只要有一个符合条件的元素则会立刻中止后续的操作立即返回一个布尔值无需遍历整个流。源码解析内部实现会调用makeRef(),其接收一个Predicate函数式接口并接收一个枚举值该值代表当前操作执行的是 ANY。如果test()抽象方法执行返回值MatchKind中any的stopOnPredicateMatches则将stop中断置为truevalue 也为true。并终进行返回。无需进行后续的流操作。4.2基于allMatch()判断条件是否匹配所有元素allMatch()的工作原理与anyMatch()类似但是anyMatch执行时只要流中有一个元素符合条件就会返回true 而allMatch会判断流中是否所有条件都符合条件全部符合才会返回true案例判断集合所有学生的年龄是否都小于20/*** author 我是七月呀* date 2020/12/22*/public class AllMatchDemo {public static void main(String[] args) {//判断集合所有学生的年龄是否都小于20ArrayList students new ArrayList();students.add(new Student(1,19,张三,M,true));students.add(new Student(1,18,李四,M,false));students.add(new Student(1,21,王五,F,true));students.add(new Student(1,20,赵六,F,false));if(students.stream().allMatch(student - student.getAge() 20)){System.out.println(集合所有学生的年龄都小于20);}else {System.out.println(集合中有年龄大于20的学生);}}}源码解析与anyMatch类似只是其枚举参数的值为ALL5、查找对于集合操作有时需要从集合中查找中符合条件的元素Stream中也提供了相关的APIfindAny()和 findFirst()他俩可以与其他流操作组合使用。findAny用于获取流中随机的某一个元素findFirst用于获取流中的 第一个元素。至于一些特别的定制化需求则需要自行实现。5.1基于findAny()查找元素案例findAny用于获取流中随机的某一个元素并且利用短路在找到结果时立即结束/*** author 我是七月呀* date 2020/12/22*/public class FindAnyDemo {public static void main(String[] args) {//findAny用于获取流中随机的某一个元素并且利用短路在找到结果时立即结束ArrayList students new ArrayList();students.add(new Student(1,19,张三1,M,true));students.add(new Student(1,18,张三2,M,false));students.add(new Student(1,21,张三3,F,true));students.add(new Student(1,20,张三4,F,false));students.add(new Student(1,20,张三5,F,false));students.add(new Student(1,20,张三6,F,false));Optional student1 students.stream().filter(student - student.getSex().equals(F)).findAny();System.out.println(student1.toString());}}结果Optional[Student{id1, age21, name张三3, sexF, isPasstrue}]此时我们将其循环100次/*** author 我是七月呀* date 2020/12/22*/public class FindAnyDemo {public static void main(String[] args) {//findAny用于获取流中随机的某一个元素并且利用短路在找到结果时立即结束ArrayList students new ArrayList();students.add(new Student(1,19,张三1,M,true));students.add(new Student(1,18,张三2,M,false));students.add(new Student(1,21,张三3,F,true));students.add(new Student(1,20,张三4,F,false));students.add(new Student(1,20,张三5,F,false));students.add(new Student(1,20,张三6,F,false));for (int i 0; i 100; i) {Optional student1 students.stream().filter(student - student.getSex().equals(F)).findAny();System.out.println(student1.toString());}}}结果由于数量较大只截取了部分截图全部都是一样的不行的小伙伴可以自己测试一下这时候我们改为串行流在执行一下/*** author 我是七月呀* date 2020/12/22*/public class FindAnyDemo {public static void main(String[] args) {//findAny用于获取流中随机的某一个元素并且利用短路在找到结果时立即结束ArrayList students new ArrayList();students.add(new Student(1,19,张三1,M,true));students.add(new Student(1,18,张三2,M,false));students.add(new Student(1,21,张三3,F,true));students.add(new Student(1,20,张三4,F,false));students.add(new Student(1,20,张三5,F,false));students.add(new Student(1,20,张三6,F,false));for (int i 0; i 100; i) {Optional student1 students.parallelStream().filter(student - student.getSex().equals(F)).findAny();System.out.println(student1.toString());}}}结果现在我们通过源码解析来分析下这是为什么根据这一段源码介绍findAny对于同一数据源的多次操作会返回不同的结果。但是我们现在的操作是串行的 所以在数据较少的情况下一般会返回第一个结果但是如果在并行的情况下那就不能确保返回的是第一个了。 这种设计主要是为了获取更加高效的性能。并行操作后续会做详细介绍。传递参数指定不必须获取第一个元素在该方法中主要用于判断对于当前的操作执行并行还是串行。在该方法中的wrapAndCopyInto()内部做的会判断流中是否存在符合条件的元素如果有的话则会进行返回。结 果终会封装到Optional中的IsPresent中。总结当为串行流且数据较少时获取的结果一般为流中第一个元素但是当为并流行的时 候则会随机获取。5.2基于findFirst()查找元素findFirst使用原理与findAny类似只是它无论串行流还是并行流都会返回第一个元素这里不做详解6、归约到现在截止对于流的终端操作我们返回的有boolean、Optional和List。但是在集合操作中我们经常会涉及 对元素进行统计计算之类的操作如求和、求大值、小值等从而返回不同的数据结果。6.1基于reduce()进行累积求和案例对集合中的元素求和/*** author 我是七月呀* date 2020/12/22*/public class ReduceDemo {public static void main(String[] args) {List integers Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);Integer reduce integers.stream().reduce(0, (integer1, integer2) - integer1 integer2);System.out.println(reduce);}}结果53在上述代码中在reduce里的第一个参数声明为初始值第二个参数接收一个lambda表达式代表当前流中的两 个元素它会反复相加每一个元素直到流被归约成一个终结果Integer reduce integers.stream().reduce(0,Integer::sum);优化成这样也是可以的。当然reduce还有一个不带初始值参数的重载方法但是要对返回结果进行判断因为如果流中没有任何元素的话可能就没有结果了。具体方法如下所示List integers Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);Optional reduce integers.stream().reduce(Integer::sum);if(reduce.isPresent()){System.out.println(reduce);}else {System.out.println(数据有误);}源码解析两个参数的reduce方法在上述方法中对于流中元素的操作当执行第一个元素会进入begin方法将初始化的值给到statestate就 是后的返回结果。并执行accept方法对state和第一个元素根据传入的操作对两个值进行计算。并把终计 算结果赋给state。当执行到流中第二个元素直接执行accept方法对state和第二个元素对两个值进行计算并把终计算结果赋 给state。后续依次类推。可以按照下述代码进行理解T result  identity;for (T element : this stream){result  accumulator.apply(result, element)}return result;源码解析单个参数的reduce方法在这部分实现中对于匿名内部类中的empty相当于是一个开关state相当于结果。对于流中第一个元素首先会执行begin()将empty置为truestate为null。接着进入到accept()判断empty是否 为true如果为true则将empty置为false同时state置为当前流中第一个元素当执行到流中第二个元素时 直接进入到accpet()判断empty是否为true此时empty为false则会执行apply()对当前state和第二个元素进 行计算并将结果赋给state。后续依次类推。当整个流操作完之后执行get(), 如果empty为true则返回一个空的Optional对象如果为false则将后计算 完的state存入Optional中。可以按照下述代码进行理解boolean flag  false;T result  null;for (T element : this stream) {if (!flag) {flag  true;result  element;}else{result  accumulator.apply(result, element);}}return flag ? Optional.of(result) : Optional.empty();6.2获取流中元素的最大值、最小值案例获取集合中元素的最大值、最小值/*** author 我是七月呀* date 2020/12/22*/public class MaxDemo {public static void main(String[] args) {List integers Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);/*** 获取集合中的最大值*///方法一Optional max1 integers.stream().reduce(Integer::max);if(max1.isPresent()){System.out.println(max1);}//方法二Optional max2 integers.stream().max(Integer::compareTo);if(max2.isPresent()){System.out.println(max2);}/*** 获取集合中的最小值*///方法一Optional min1 integers.stream().reduce(Integer::min);if(min1.isPresent()){System.out.println(min1);}//方法二Optional min2 integers.stream().min(Integer::compareTo);if(min2.isPresent()){System.out.println(min2);}}}结果Optional[8]Optional[8]Optional[1]Optional[1]7、收集器通过使用收集器可以让代码更加方便的进行简化与重用。其内部主要核心是通过Collectors完成更加复杂的计算 转换从而获取到终结果。并且Collectors内部提供了非常多的常用静态方法直接拿来就可以了。比方说 toList。/*** author 我是七月呀* date 2020/12/22*/public class CollectDemo {public static void main(String[] args) {ArrayList students new ArrayList();students.add(new Student(1,19,张三,M,true));students.add(new Student(1,18,李四,M,false));students.add(new Student(1,21,王五,F,true));students.add(new Student(1,20,赵六,F,false));//通过counting()统计集合总数 方法一Long collect students.stream().collect(Collectors.counting());System.out.println(collect);//结果 4//通过count()统计集合总数 方法二long count students.stream().count();System.out.println(count);//结果 4//通过maxBy求最大值Optional collect1 students.stream().collect(Collectors.maxBy(Comparator.comparing(Student::getAge)));if(collect1.isPresent()){System.out.println(collect1);}//结果 Optional[Student{id1, age21, name王五, sexF, isPasstrue}]//通过max求最大值Optional max students.stream().max(Comparator.comparing(Student::getAge));if(max.isPresent()){System.out.println(max);}//结果 Optional[Student{id1, age21, name王五, sexF, isPasstrue}]//通过minBy求最小值Optional collect2 students.stream().collect(Collectors.minBy(Comparator.comparing(Student::getAge)));if(collect2.isPresent()){System.out.println(collect2);}//结果 Optional[Student{id1, age18, name李四, sexM, isPassfalse}]//通过min求最小值Optional min students.stream().min(Comparator.comparing(Student::getAge));if(min.isPresent()){System.out.println(min);}//结果 Optional[Student{id1, age18, name李四, sexM, isPassfalse}]//通过summingInt()进行数据汇总Integer collect3 students.stream().collect(Collectors.summingInt(Student::getAge));System.out.println(collect3);//结果 78//通过averagingInt()进行平均值获取Double collect4 students.stream().collect(Collectors.averagingInt(Student::getAge));System.out.println(collect4);//结果 19.5//通过joining()进行数据拼接String collect5 students.stream().map(Student::getName).collect(Collectors.joining());System.out.println(collect5);//结果 张三李四王五赵六//复杂结果的返回IntSummaryStatistics collect6 students.stream().collect(Collectors.summarizingInt(Student::getAge));double average collect6.getAverage();long sum collect6.getSum();long count1 collect6.getCount();int max1 collect6.getMax();int min1 collect6.getMin();}}8、分组在数据库操作中经常会通过group by对查询结果进行分组。同时在日常开发中也经常会涉及到这一类操作 如通过性别对学生集合进行分组。如果通过普通编码的方式需要编写大量代码且可读性不好。对于这个问题的解决java8也提供了简化书写的方式。通过 Collectors。groupingBy()即可。//通过性别对学生进行分组Map collect students.stream().collect(Collectors.groupingBy(Student::getSex));结果 {F[Student{id1, age21, name王五, sexF, isPasstrue}, Student{id1, age20, name赵六, sexF, isPassfalse}],M[Student{id1, age19, name张三, sexM, isPasstrue}, Student{id1, age18, name李四, sexM, isPassfalse}]}8.1多级分组刚才已经使用groupingBy()完成了分组操作但是只是通过单一的sex进行分组那现在如果需求发生改变还要 按照是否及格进行分组能否实现答案是可以的。对于groupingBy()它提供了两个参数的重载方法用于完成这 种需求。这个重载方法在接收普通函数之外还会再接收一个Collector类型的参数其会在内层分组(第二个参数)结果传 递给外层分组(第一个参数)作为其继续分组的依据。//现根据是否通过考试对学生分组在根据性别分组Map collect1 students.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getPass)));结果 {F{false[Student{id1, age20, name赵六, sexF, isPassfalse}],true[Student{id1, age21, name王五, sexF, isPasstrue}]},M{false[Student{id1, age18, name李四, sexM, isPassfalse}],true[Student{id1, age19, name张三, sexM, isPasstrue}]}}8.2多级分组变形在日常开发中我们很有可能不是需要返回一个数据集合还有可能对数据进行汇总操作比方说对于年龄18岁 的通过的有多少人未及格的有多少人。因此对于二级分组收集器传递给外层分组收集器的可以任意数据类型 而不一定是它的数据集合。//根据年龄进行分组获取并汇总人数Map collect2 students.stream().collect(Collectors.groupingBy(Student::getAge, Collectors.counting()));System.out.println(collect2);结果{181, 191, 201, 211}//要根据年龄与是否及格进行分组并获取每组中年龄的学生Map collect3 students.stream().collect(Collectors.groupingBy(Student::getAge, Collectors.groupingBy(Student::getPass,Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(Student::getAge)), Optional::get))));System.out.println(collect3.toString());结果{18{falseStudent{id1, age18, name李四, sexM, isPassfalse}},19{trueStudent{id1, age19, name张三, sexM, isPasstrue}},20{falseStudent{id1, age20, name赵六, sexF, isPassfalse}},21{trueStudent{id1, age21, name王五, sexF, isPasstrue}}}
http://www.pierceye.com/news/36719/

相关文章:

  • 广东事业单位网站南通做百度网站的公司哪家好
  • 网站制作的知识莱芜区政协网站
  • 网站后台登陆图片wordpress4.0.6 漏洞
  • .net开发的网站有哪些刷单网站建设
  • 政务公开和网站建设石景山高端网站建设
  • 恩施网站建设模板品牌策划大赛作品
  • 网站源码制作步骤深圳福田商城网站建设
  • 网站域名备案查询系统cms后台管理系统
  • 微信里面的小程序做神马网站优化排名
  • 东莞网站se外贸流程和专业知识点
  • 昆山做网站公司哪家好ui设计学什么
  • 建网站的步骤和方法界面设计器
  • 给客户做网站外贸展示网站多少钱
  • 做门窗网站怎么做全国企业信用公示信息公示网官网
  • 手机建网站软件wordpress无法进入文章
  • 网站域名与网站首页网址自己怎么在手机上设计装修
  • 怎么给QQ名片做网站哪些网站的做的好看的
  • 学做面包的网站wordpress totalpoll
  • 网站制作的页面比例大学生就业信息招聘网
  • 网站建设需要多少钱wordpress怎么获取数据
  • 网站可以改内链结构吗大连建设招标网
  • 网站建设行吗企业网网站怎么做
  • 网站ui设计欣赏设计师做兼职的网站
  • 软文发稿网站广州免费网站建设
  • 大理市建设局网站邢台同城
  • 宁夏建设厅网站6网页视觉设计是什么
  • 视频网站做app还是h5只用html5做网站
  • 网站建设模板简单html免费网页素材
  • 创建一个网站需要做哪些工作东莞 手机网站制作
  • 自己做图片的网站网站域名到期