0%

Java 函数式编程(三):函数式数据处理:强大方便的收集器

1. 怎样理解 collect

  • 定义:<R, A> R collect(Collector<? super T, A, R> collector)
  • 它接受一个收集器 collector 作为参数,类型是 Collector,这是一个接口

2. 与 toList 类似的容器收集器还有哪些

  • toSet:可以排重。toList 背后的容器是 ArrayListtoSet 背后的容器是 HashSet
  • toCollection:通用的容器收集器,可以用于任何 Collection 接口的实现类。比如,如果希望排重但又希望保留出现的顺序,可以使用 LinkedHashSetCollector 可以这么创建:Collectors.toCollection(LinkedHashSet::new);
  • toMap:将元素流转换为一个 MapMap 有键和值两部分,toMap 至少需要两个参数,一个将元素转换为键,另一个将元素转换为值

3. 怎样理解字符串收集器

  • 除了将元素流收集到容器中,另一个常见的操作是收集为一个字符串

  • 针对这种需求,Collectors 提供了 joining 收集器

    • public static Collector<CharSequence, ?, String> joining():简单地把元素连接起来
    • public static Collector<CharSequence, ?, String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix):支持一个分隔符,还可以给整个结果字符串加前缀和后缀
  • joining 收集器的内部也利用了 StringBuilder

4. 怎样理解分组

  • 分组类似于数据库查询语言 SQL 中的 group by 语句,它将元素流中的每个元素分到一个组,可以针对分组再进行处理和收集

  • 最基本的分组收集器为:public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier)

    • 参数是一个类型为 Function 的分组器 classifier,它将类型为 T 的元素转换为类型为 K 的一个值,这个值表示分组值
    • 所有分组值一样的元素会被归为同一个组,放到一个列表中,所以返回值类型是 Map<K, List<T>>
  • 分组计数、找最大/最小元素:将元素按一定标准分为多组,然后计算每组的个数,按一定标准找最大或最小元素。Collectors 提供了一些对应的收集器,一般用作下游收集器,比如 maxByminBycounting

  • 分组数值统计:除了基本的分组计数,还经常需要进行一些分组数值统计,比如求学生分数的和、平均分、最高分、最低分等,针对 intlongdouble 类型,Collectors 提供了专门的收集器

  • 分组内的 map:对于每个分组内的元素,我们感兴趣的可能不是元素本身,而是它的某部分信息

    • 在 Stream API 中,Streammap 方法,可以将元素进行转换,Collectors 也为分组元素提供了函数 mapping:交给下游收集器 downstream 的不再是元素本身,而是应用转换函数 mapper 之后的结果
    • StreamflatMap 方法,Java 9Collectors 增加了分组内的 flatMap 方法 flatMapping,它与 mapping 的关系如同 StreamflatMapmap 的关系
    • 分组结果处理(filtersortskiplimit):Collector 没有专门的收集器,但有一个通用的方法:public static<T, A, R, RR> Collector<T, A, RR> collectingAndThen(Collector<T, A, R> downstream, Function<R, RR> finisher),接受一个下游收集器 downstream 和 一个 finisher,返回一个收集器
    • 分区:分组的一个特殊情况是分区,就是将流按 truefalse 分为两个组。Collectors 有专门的分区函数 partitioningBy()
    • 多级分组groupingByparttitionBy 都可以接受一个下游收集器,对同一个分组或分区内的元素进行进一步收集,而下游收集器又可以是分组或分区,以构建多级分组
-------------------- 本文结束感谢您的阅读 --------------------