Stream-数据操作

Python030

Stream-数据操作,第1张

将两个Stream连接在一起,合成一个Stream。若两个输入的Stream都是排序的,则新Stream也是排序的;若输入的Stream中任何一个是并行的,则新的Stream也是并行的;若关闭新的Stream时,原两个输入的Stream都将执行关闭处理。

除掉原Stream中重复的元素,生成的新Stream中没有没有重复的元素。

对原Stream按照指定条件过滤,在新建的Stream中,只包含满足条件的元素,将不满足条件的元素过滤掉。

map方法将对于Stream中包含的元素使用给定的转换函数进行转换操作,新生成的Stream只包含转换生成的元素。

为了提高处理效率,官方已封装好了,三种变形:mapToDouble,mapToInt,mapToLong。如果想将原Stream中的数据类型,转换为double,int或者是long是可以调用相对应的方法。

flatMap方法与map方法类似,都是将原Stream中的每一个元素通过转换函数转换,不同的是,该换转函数的对象是一个Stream,也不会再创建一个新的Stream,而是将原Stream的元素取代为转换的Stream。如果转换函数生产的Stream为null,应由空Stream取代。flatMap有三个对于原始类型的变种方法,分别是:flatMapToInt,flatMapToLong和flatMapToDouble。

peek方法生成一个包含原Stream的所有元素的新Stream,同时会提供一个消费函数(Consumer实例),新Stream每个元素被消费的时候都会执行给定的消费函数,并且消费函数优先执行

skip方法将过滤掉原Stream中的前N个元素,返回剩下的元素所组成的新Stream。如果原Stream的元素个数大于N,将返回原Stream的后(原Stream长度-N)个元素所组成的新Stream;如果原Stream的元素个数小于或等于N,将返回一个空Stream。

对原Stream进行排序,返回一个有序列的新Stream。sorterd有两种变体sorted(),sorted(Comparator),前者将默认使用Object.equals(Object)进行排序,而后者接受一个自定义排序规则函数(Comparator),可按照意愿排序。

在Stream接口提供了Collect的方法:

Collector是Stream的可变减少操作接口(可变减少操作如:集合转换计算元素相关的统计信息,例如sum,min,max或average等)

Collector<T, A, R>接受三个泛型参数,对可变减少操作的数据类型作相应限制:

T:输入元素类型

A:可变处理函数

R:结果类型

Collector接口声明了4个函数,一起协作,将元素放入容器,经过转换输出想要结果:

对于前面提到了很多Stream的链式操作,但是,我们总是要将Strea生成一个集合,比如:

如希望生成一个不是由Stream类库自动指定的一种类型(如TreeSet)。此时使用toCollection,它接受一个函数作为参数, 来创建集合。

toMap最少应接受两个参数,一个用来生成key,另外一个用来生成value。toMap方法有三种变形:

toMap(Function<? super T, ? extends K>keyMapper,Function<? super T, ? extends U>valueMapper)

使用collect可以将Stream转换成值。如maxBy和minBy允许用户按照某个特定的顺序生成一个值。

collect的一个常用操作将Stream分解成两个集合。

数据分组是一种更自然的分割数据操作, 与将数据分成true和false两部分不同,可以使用任意值对数据分组。

调用Stream的collect方法,传入一个收集器,groupingBy接受一个分类函数,用来对数据分组,就像partitioningBy一样,接受一个

Predicate对象将数据分成true和false两部分。我们使用的分类器是一个Function对象,和map操作用到的一样。

可以将Colletor 组合起来使用

求一段数字的和,如果是奇数,直接相加;如果是偶数,乘以2后在相加

forEachOrdered方法与forEach类似,都是遍历Stream中的所有元素,不同的是,如果该Stream预先设定了顺序,会按照预先设定的顺序执行(Stream是无序的),默认为元素插入的顺序。

Ref:

https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/

https://www.baeldung.com/java-8-collectors

https://blog.csdn.net/IO_Field/article/details/54971608

你说需要计算一个月有多少周,若是指,一月,二月一直到十二月每个月有多少周的话,可以用Java8的新时间API进行计算,因为里面已经封装了每个月了,但由于每一年每个月的周数可能不同,所以必须还需要一个日期,也就是年,因此得到某年某月的某个时间,就可以相应算出这个时间所在月的第一天和最后一天,然后计算这第一天和最后一天相隔多少个周

思路:

获取所有月份的枚举集合A

随意获取一个时间B

循环所有的月份A,把B的月份依次修改为A中的每个月份,得到修改后的时间集合C

循环C中的所有时间,把每个时间都算出该时间的所在月份的第一天和最后一天,并计算周数

打印周数

代码:

// 随意取一个时间,取了当前时间

LocalDate localDate = LocalDate.now()

System.out.println("当前时间为:" + localDate)

// 根据封装好的月份获取一个一月到十二月的Month流,此时流里的对象为Month

Arrays.stream(Month.values())

      // 把每个month都调整到当前这个时间里,此时流的对象为LocalDate

      .map(month -> month.adjustInto(localDate))

      // 这里方便里观察此时流的数据,把转换后的时间打印了出来

      .peek(System.out::println)

      // 根据时间的所在月的第一天和最后一天作为间隔计算周数

      .map(temporal -> ChronoUnit.WEEKS.between(temporal.with(TemporalAdjusters.firstDayOfMonth()), temporal.with(TemporalAdjusters.lastDayOfMonth())))

      // 打印最后的周数

      .forEach(System.out::println)