作者个人研发在高并发场景下提供了一个简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。开源半年多以来,已成功为十几家中小企业提供精准定时调度解决方案,经受住了生产环境的考验。为了造福更多的童鞋,这里提供一个开源的框架地址:https://github.com/sunshinelyz/mykit-delayStream的中间操作多个中间操作可以连接起来形成管道,除非终止操作在管道,否则中间操作不做任何处理!并且当操作终止时,一次性全部处理,称为“惰性求值”。Stream的中间操作不会输出任何结果数据。Stream的中间操作可以分为:筛选切片、映射、排序。接下来,我们简要描述这些中间操作。过滤和切片这里我把过滤和切片相关的操作整理成下表。接下来,我们列举几个简单的例子来加深理解。为了更好的测试程序,我先构造了一个对象数组,如下图。protectedListlist=Arrays.asList(newEmployee("张三",18,9999.99),newEmployee("李四",38,5555.55),newEmployee("王武",60,6666.66),newEmployee("赵三"六",8,7777.77),newEmployee("天启",58,3333.33));其中,Employee类的定义如下。@Data@Builder@ToString@NoArgsConstructor@AllArgsConstructorpublicclassEmployeeimplementsSerializable{privatestaticfinallongserialVersionUID=-9079722457749166858L;privateStringname;privateIntegerage;privateDoublesalary;}Employee类的定义比较简单,这里不再赘述。在下面的例子中,我们都是使用Employee对象的集合来进行操作。好了,下面开始具体的操作案例。1.filter()方法filter()方法主要用于接收Lambda表达式,从流中排除某些元素。它在Stream接口中的源码如下。流过滤器(谓词<?superT>谓词);可以看到在filter()方法中,需要传递Predicate接口的对象。Predicate接口是什么鬼?点击查看源代码。@FunctionalInterfacepublicinterfacePredicate{booleantest(Tt);defaultPredicateand(Predicateother){Objects.requireNonNull(other);return(t)->test(t)&&other.test(t);}defaultPredicatenegate(){return(t)->!test(t);}defaultPredicateor(Predicateother){Objects.requireNonNull(other);return(t)->test(t)||other.test(t);}staticPredicateisEqual(ObjecttargetRef){return(null==targetRef)?Objects::isNull:object->targetRef.equals(object);}}可以看到,Predicate是一个函数式接口,其中接口中定义的主要方法是test()方法,它接收一个泛型对象t并返回一个boolean类型的数据。看到这里,相信大家都明白了:filter()方法是根据Predicate接口的test()方法的返回结果来过滤数据的。如果test()方法的返回结果为真,则符合规则;如果test()方法返回结果为false,则不满足规则。这里,我们可以用下面的例子来简单说明一下filter()方法的使用方法。//内部迭代:这个过程中没有进行过迭代,通过Streamapi进行迭代//中间操作:不会进行任何操作Streamstream=list.stream().filter((e)->{System.out.println("StreamAPI中间操作");return.getAge()>30;});执行终止语句后,我们在不迭代上述集合的同时进行迭代打印。实际上,这是内部迭代,由StreamAPI完成。再来看看外部迭代,也就是我们的人工迭代。//外部迭代Iteratorit=list.iterator();while(it.hasNext()){System.out.println(it.next());}2.limit()方法主要作用是:截断Stream使其元素不超过给定的数量。首先看一下limit方法的定义,如下图。流限制(longmaxSize);Stream接口中limit()方法的定义比较简单,只需要传入一个long类型的数字即可。我们可以使用如下代码所示的limit()方法。//过滤后取2个值list.stream().filter((e)->e.getAge()>30).limit(2).forEach(System.out::println);这里,我们可以配合其他的中间操作,切断流,这样就可以得到对应数量的元素了。并且在上面的计算中,只要有2个元素满足条件,就不会继续往下迭代数据,可以提高效率。3.skip()方法跳过元素并返回一个流,其中前n个元素被丢弃。如果流包含的元素少于n个,则返回一个空流。与limit(n)互补。源码定义如下。流跳过(长);源码定义比较简单,只需要传入一个long类型的数字,其含义是跳过n个元素。一个简单的例子如下所示。//跳过前2个值list.stream().skip(2).forEach(System.out::println);4.distinct()方法过滤,流生成的元素的hashCode()和equals()去除重复元素。源码定义如下。流区别();旨在对流中的元素进行重复数据删除。我们可以使用distinct()方法如下。list.stream().distinct().forEach(System.out::println);这里需要注意一点:distinct需要重写实体中的hashCode()和equals()方法才能使用。映射与映射相关的方法如下表所示。1.map()方法接收一个函数作为参数,该函数将应用于每个元素并映射成一个新元素。我们先看一下Java8中map()方法的Stream接口的声明,如下所示。Streammap(Functionmapper);我们可以按如下方式使用map()方法。//将流中的每个元素映射到map函数,每个元素执行这个函数,然后返回Listlist=Arrays.asList("aaa","bbb","ccc","ddd");list.stream().map((e)->e.toUpperCase()).forEach(System.out::printf);//获取Person中每个人的名字,然后返回一个集合Listnames=this.list.stream().map(Person::getName).collect(Collectors.toList());2.flatMap()接收一个函数作为参数,将流中的每个值都变成另一个流,然后将所有流拼接成一个流。我们先看一下Java8中Stream接口的flatMap()方法的声明,如下所示。StreamflatMap(函数>mapper);我们可以通过以下方式使用flatMap()方法。为了方便大家的理解,这里贴出所有代码的测试flatMap()方法。/***flatMap——接收一个函数作为参数,将流中的每个值替换为一个流,然后将所有流连接成一个流*/@TestpublicvoidtestFlatMap(){StreamAPI_Tests=newStreamAPI_Test();Listlist=Arrays.asList("aaa","bbb","ccc","ddd");list.stream().flatMap((e)->s.filterCharacter(e)).forEach(System.out::println);//如果使用map,需要这样写list.stream().map((e)->s.filterCharacter(e)).forEach((e)->{e.forEach(System.out::println);});}/***将字符串转换为流*/publicStreamfilterCharacter(Stringstr){Listlist=newArrayList<>();for(Characterch:str.toCharArray()){list.add(ch);}returnlist.stream();}其实map方法就相当于Collaction的add方法。如果add是一个集合,就会变成一个二维数组,而flatMap相当于Collaction的addAll方法,如果参数是一个集合,只是把两个集合合并,而不是变成一个二维数组.排序与排序相关的方法如下表所示。从上表可以看出:sorted有两种方法,一种是不传参数,称为自然排序,另一种是传递Comparator接口参数,称为自定义排序。我们先看下Java8中Stream接口对sorted()方法的声明,如下所示。流已排序();流排序(比较器<?superT>比较器);sorted()方法的定义比较简单,就不赘述了。我们还可以使用Stream的sorted()方法,如下所示。/自然排序Listpersons=list.stream().sorted().collect(Collectors.toList());//自定义排序Listpersons1=list.stream().sorted((e1,e2)->{if(e1.getAge()==e2.getAge()){return0;}elseif(e1.getAge()>e2.getAge()){return1;}else{return-1;}}).collect(Collectors.toList());写在最后。如果觉得文章对您有帮助,请在微信搜索并关注“冰河科技”微信公众号,向冰河学习Java8的新特性。最后附上Java8新特性核心知识图谱,祝大家在学习Java8新特性时少走弯路。本文转载自微信公众号“冰河科技”,可通过以下二维码关注。转载本文请联系冰川科技公众号。