为什么在聚合操作中需要Collector.toList()?

时间:2014-12-07 04:22:48

标签: java aggregate

有人可以解释为什么我们在第一次聚合操作中需要最后一个表达式Collectors.toList()而在第二次和第三次操作中不需要吗?

Map<Person.Sex, List<String>> namesByGender =
  roster
     .stream()
     .collect(
        Collectors.groupingBy(
            Person::getGender,
            Collectors.mapping(
               Person::getName,
               Collectors.toList()))); // why need toList here?

Map<Person.Sex, Integer> totalAgeByGender =
   roster
    .stream()
    .collect(
        Collectors.groupingBy(
           Person::getGender,
           Collectors.reducing(
              0,
              Person::getAge,
              Integer::sum)));

Map<Person.Sex, List<Person>> byGender =
  roster
   .stream()
   .collect(
      Collectors.groupingBy(Person::getGender)); //without toList() 

1 个答案:

答案 0 :(得分:1)

groupingBy收集器在Map中创建条目。 Map包含键值对,因此我们说它是Map<K,V>。为了分组到地图,我们需要一个确定密钥的方法,我们需要一个收集值的方法。

在第二种情况下,价值的收集是按性别加总值 - 按性别划分的总年龄。 Map的类型为Map<Person.Sex, *Integer*>。这意味着地图的关键是性别,为该关键字存储的值是该性别的总年龄。因此,分组需要Person.Sex,而集合是 sum ,这意味着集合将 int 值转换为 {{ 1}} 值,使用 Integer 方法对Integer.sum()的返回值进行求和。

在第一种情况下,值的集合是按性别列出所有名称。 Person.getAge()的类型为Map。这意味着地图的关键字是性别,为密钥存储的值是{em> Map<Person.Sex, *List<String>*> List s(名称)。因此,分组需要String,而列出名称,这意味着该集合将 Person.Sex 值转换为 String 使用 List<String> 返回的相应收集器将它们收集到列表中。