Java8 Collector总结
一、概述
Collector是专门用来作为Stream的collect方法的参数的。
1 | public interface Stream<T> extends BaseStream<T, Stream<T>> { |
而Collectors是作为生产具体Collector的工具类。
二、Collector
Collector主要包含五个参数,它的行为也是由这五个参数来定义的,如下所示:
1 | public interface Collector<T, A, R> { |
Collector拥有两个of方法用于生成Collector实例,其中一个拥有上面所有五个参数,另一个四个参数,不包括finisher。
1 | public interface Collector<T, A, R> { |
Characteristics:这个特征值是一个枚举,拥有三个值:CONCURRENT(多线程并行),UNORDERED(无序),IDENTITY_FINISH(无需转换结果)。其中四参of方法中没有finisher参数,所以必有IDENTITY_FINISH特征值。
三、Collectors
Collectors是一个工具类,是JDK预实现Collector的工具类,它内部提供了多种Collector,我们可以直接拿来使用,非常方便。
5.6.1 toCollection
将流中的元素全部放置到一个集合中返回,这里使用Collection,泛指多种集合。
1 | public class CollectorsTest { |
5.6.2 toList
将流中的元素放置到一个列表集合中去。这个列表默认为ArrayList。
1 | public class CollectorsTest { |
5.6.3 toSet
将流中的元素放置到一个无序集set中去。默认为HashSet。
1 | public class CollectorsTest { |
5.6.4 joining
joining的目的是将流中的元素全部以字符序列的方式连接到一起,可以指定连接符,甚至是结果的前后缀。
1 | public class CollectorsTest { |
执行结果:
1 | 1234567891101212121121asdaa3e3e3e2321eew |
StringJoiner:这是一个字符串连接器,可以定义连接符和前后缀,正好适用于实现第三种joining方法。
5.6.5 mapping
这个映射是首先对流中的每个元素进行映射,即类型转换,然后再将新元素以给定的Collector进行归纳。
1 | public class CollectorsTest { |
实例中截取字符串列表的前5个元素,将其分别转换为Integer类型,然后放到一个List中返回。
5.6.6 collectingAndThen
该方法是在归纳动作结束之后,对归纳的结果进行再处理。
1 | public class CollectorsTest { |
执行结果为:
1 | 8 |
5.6.7 counting
该方法用于计数。
1 | public class CollectorsTest { |
结果:
1 | 8 |
5.6.8 minBy/maxBy
生成一个用于获取最小/最大值的Optional结果的Collector。
1 | public class CollectorsTest { |
执行结果为:
1 | Optional[212121121] |
5.6.9 summingInt/summingLong/summingDouble
生成一个用于求元素和的Collector,首先通过给定的mapper将元素转换类型,然后再求和。
参数的作用就是将元素转换为指定的类型,最后结果与转换后类型一致。
1 | public class CollectorsTest { |
执行结果为:
1 | 1368 |
5.6.10 averagingInt/averagingLong/averagingDouble
生成一个用于求元素平均值的Collector,首选通过参数将元素转换为指定的类型。
参数的作用就是将元素转换为指定的类型,求平均值涉及到除法操作,结果一律为Double类型。
1 | public class CollectorsTest { |
执行结果为:
1 | 456.0 |
5.6.11 reducing
reducing方法有三个重载方法,其实是和Stream里的三个reduce方法对应的,二者是可以替换使用的,作用完全一致,也是对流中的元素做统计归纳作用。
1 | public final class Collectors { |
实例:
1 | public class CollectorsTest { |
1 | Optional[13] |
效果可参见Java流式操作系列-Stream
5.6.12 groupingBy
这个方法是用于生成一个拥有分组功能的Collector,它也有三个重载方法:
1 | public final class Collectors { |
实例:
1 | public class CollectorsTest { |
执行结果为:
1 | {3=[123, 456, 789], 4=[1101], 5=[asdaa], 6=[3e3e3e], 7=[2321eew], 9=[212121121]} |
groupingBy方法还有并发版的groupingByConcurrent,功能基本一致,只是返回的Collector是并行的。
5.6.13 partitioningBy
该方法将流中的元素按照给定的校验规则的结果分为两个部分,放到一个map中返回,map的键是Boolean类型,值为元素的列表List。
该方法有两个重载方法:
1 | public final class Collectors { |
实例:
1 | public class CollectorsTest { |
执行结果:
1 | {false=[123, 456, 789, 1101, asdaa], true=[212121121, 3e3e3e, 2321eew]} |
5.6.14 toMap
toMap方法是根据给定的键生成器和值生成器生成的键和值保存到一个map中返回,键和值的生成都依赖于元素,可以指定出现重复键时的处理方案和保存结果的map。
1 | public final class Collectors { |
实例:
1 | public class CollectorsTest { |
执行结果:
1 | {1=123, 4=456, 7=789} |
第一种方式中,如果不添加limit限制,就会抛出异常。
还有并发的版本:toConcurrentMap,同样三种重载方法,与toMap基本一致,只是它最后使用的map是并发Map:ConcurrentHashMap。
5.6.15 summarizingInt/summarizingLong/summarizingDouble
这三个方法适用于汇总的,返回值分别是IntSummaryStatistics,LongSummaryStatistics,DoubleSummaryStatistics。
在这些返回值中包含有流中元素的指定结果的数量、和、最大值、最小值、平均值。所有仅仅针对数值结果。
1 | public class CollectorsTest { |
执行结果:
1 | IntSummaryStatistics{count=8, sum=40, min=3, average=5.000000, max=9} |
最后我们可以从返回的汇总实例中获取到想要的汇总结果。
四、总结
整个Collectors工具类就是在为Collector服务,用于创建各种不同的Collector。部分功能与Stream中的方法重合了,为了简化代码,完全不必采用Collectors实现,优先Stream方法。
作者:唯一浩哥
链接:https://www.jianshu.com/p/7eaa0969b424
来源:简书
- 本文作者: GermMC
- 本文链接: http://blog.germmc.com/2020/06/09/Collector/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!