Java 下游收集器

Java 下游收集器,用户希望对 groupingBypartitioningBy 操作返回的集合进行后期处理,使用 java.util.stream.Collectors 类定义的某种静态工具方法。有关将元素划分为多个类别的讨论请参见范例分区与分组

Java 下游收集器 问题描述

用户希望对 groupingBypartitioningBy 操作返回的集合进行后期处理。

Java 下游收集器 解决方案

使用 java.util.stream.Collectors 类定义的某种静态工具方法。

Java 下游收集器 具体实例

有关将元素划分为多个类别的讨论请参见范例分区与分组groupingBypartitioningBy 方法返回的是 Map,其中键为类别(对于 partitioningBy 方法是布尔值 truefalse,对于 groupingBy 方法是对象),值为满足各个类别的元素列表。读者或许还记得根据偶数和奇数长度对字符串进行分区的示例(例 4-20),为便于参考,例 4-22 完整复制了这个示例。

例 4-22 根据偶数或奇数长度对字符串分区

List<String> strings = Arrays.asList("this", "is", "a", "long", "list", "of",
        "strings", "to", "use", "as", "a", "demo");

Map<Boolean, List<String>> lengthMap = strings.stream()
    .collect(Collectors.partitioningBy(s -> s.length() % 2 == 0));

lengthMap.forEach((key,value) -> System.out.printf("%5s: %s%n", key, value));
//
// false: [a, strings, use, a]
// true: [this, is, long, list, of, to, as, demo]

较之实际的列表,我们或许对每个类别包含多少元素更感兴趣。换言之,我们可能只需要各个列表中的元素数量,而不是返回 Map(值为 List<String>)。partitioningBy 方法的重载形式如下,其第二个参数为 Collector 类型:

static <T,D,A> Collector<T,?,Map<Boolean,D>>     partitioningBy(
    Predicate<? super T> predicate, Collector<? super T,A,D> downstream)

静态方法 Collectors.counting 的作用就在于此,其用法如例 4-23 所示。

例 4-23 对已分区的字符串进行计数

Map<Boolean, Long> numberLengthMap = strings.stream()
    .collect(Collectors.partitioningBy(s -> s.length() % 2 == 0,
                 Collectors.counting()));  ➊

numberLengthMap.forEach((k,v) -> System.out.printf("%5s: %d%n", k, v));
//
// false: 4
// true: 8

➊ 下游收集器
这就是所谓的下游收集器,它对下游的结果列表(即在分区操作完成之后)进行后期处理。
groupingBy 方法也有一种传入下游收集器的重载形式:

/**
* @param <T>:输入元素的类型
* @param <K>:键的类型
* @param <A>:下游收集器的中间累加类型
* @param <D>:下游归约操作的结果类型
* @param classifier:将输入元素映射到键的分类器函数
* @param downstream:实现下游归约操作的Collector
* @return:实现级联分组操作的Collector
*/
static <T,K,A,D> Collector<T,?,Map<K,D>>        groupingBy(
    Function<? super T,? extends K> classifier,
    Collector<? super T,A,D> downstream)

方法签名中包含了部分 Javadoc 注释,其中 T 为集合中元素的类型,K 为结果映射的键类型,A 为累加器,D 为下游收集器的类型,? 表示“未知”。有关泛型在 Java 8 中的应用,详细信息请参见泛型与 Java 8
Stream 接口定义的部分方法在 Collectors 类中存在类似的对应,它们的对比如表 4-2 所示。
表4-2:Stream接口定义的方法与Collectors类定义的方法

Stream Collectors
count counting
map mapping
min minBy
max maxBy
IntStream.sum summingInt
DoubleStream.sum summingDouble
LongStream.sum summingLong
IntStream.summarizing summarizingInt
DoubleStream.summarizing summarizingDouble
LongStream.summarizing summarizingLong

需要再次强调的是,下游收集器用于对上游操作(如分区或分组)产生的对象集合进行后期处理。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程