在Java API中分组是什么意思以及如何使用它?

时间:2017-04-21 12:06:35

标签: java api collectors

我正在查看有关收集器的Java API。

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#groupingBy-java.util.function.Function-java.util.function.Supplier-java.util.stream.Collector-

public static <T,K,D,A,M extends Map<K,D>> Collector<T,?,M> groupingBy(Function<? super T,? extends K> classifier,
                                                                       Supplier<M> mapFactory,
                                                                       Collector<? super T,A,D> downstream)
  

类型参数:

     

T - 输入元素的类型

     

K - 键的类型

     

A - 下游收集器的中间累积类型

     

D - 下游减少的结果类型

     

M - 生成的Map的类型

     

参数:

     

分类器 - 将输入元素映射到键

的分类器函数      

下游 - 实施下游减少的收集器

     

mapFactory - 一个函数,在调用时会生成一个新的空Map   期望的类型

     

返回:

     

实现级联分组操作的收集器

从第一行代码中,我了解到它是一个公共静态方法,但<T, K, D, A, M extends Map<K, D>>是什么意思?

然后从Collector<T, ?, M>,我可以理解它会返回一个收集器,但?的含义是什么。

此外,我进入了其中一个参数Supplier的页面,因为它是一个功能界面,它只有一个名为get的抽象方法,但我根本不知道如何使用它所有。我正在阅读的这本书教我们使用TreeMap::new

我在这里的困惑是参数如何需要实现Supplier接口的东西但是我们能够使用方法参考呢?

提前致谢!

2 个答案:

答案 0 :(得分:2)

  1. <T, K, D, A, M extends Map<K, D>>表示此方法使用5种通用类型参数 - TKDAM M必须实施Map<K, D>

  2. ?表示外卡,即您不关心它是什么类型。请注意,这与添加另一个泛型类型参数不同。如果它是另一个泛型类型参数,比如U,它可以在后面的代码中引用。您关心

  3. Supplier表示不接受任何参数并返回某种类型值的方法。 TreeMap::new没有参数,它会为您提供TreeMap,因此可以在此处使用此方法参考。

答案 1 :(得分:1)

<T,K,D,A,M extends Map<K,D>> - 这些是此函数的通用参数,用作此函数的参数和结果通用参数。所以,你的参数必须是:

  • Function<? super T,? extends K> classifier - 需要T并返回K
  • 的函数
  • Supplier<M> mapFactory - 供应商创建M
  • Collector<? super T,A,D> downstream - 包含TAD参数的收藏家(详情请参阅详细说明和文档)

此函数也会生成Collector<T,?,M> - 此处为TM。所有这些参数都应明确或隐式指定。

关于收集器参数,您可以转到Collector documentation page并查看Collector类的第二个通用参数是

  

还原操作的可变累积类型(通常作为实现细节隐藏)

通常,你不关心这种可变积累类型,因为最后你只需要结果,在这种情况下,结果是M

关于供应商 - 我还建议转到documentation page。它是一个方法T get()的接口。此TreeMap::new可以表示为() -> new TreeMap<>()。如果这还不清楚,那么你可能需要阅读一些关于匿名类,函数接口和lambda函数(以及方法引用)的教程。