2014-12-07 61 views
0

有人可以解釋爲什麼我們需要在第一個集合操作中的最後一個表達式Collectors.toList(),但不是在第二個和第三個集合操作中?爲什麼在集合操作中需要Collector.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() 
+0

你想在這裏做什麼?你看過功能的簽名嗎? – 2014-12-07 04:27:49

+0

我不完全理解你的問題。這兩個分組中使用了兩個完全不同的下游收集器。第一個執行地圖操作,第二個執行縮小操作。 – isnot2bad 2014-12-07 04:28:33

+0

我看到兩個聚合返回地圖實例,但一個有toList,另一個沒有。所以,這就是爲什麼我想知道toList在第一個聚合操作 – PMH 2014-12-07 04:33:27

回答

1

groupingBy收集器在Map中創建條目。 A Map包含鍵值對,所以我們說它是一個Map<K,V>。爲了組合成一個映射,我們需要一個確定鍵的方法,並且我們需要一個收集值的方法。

在第二種情況下,值的集合是將性別值加起來,即按性別總年齡。 Map類型爲Map<Person.Sex, *Integer*>。這意味着地圖的關鍵是性別,存儲的關鍵值是該性別的總年齡。所以分組需要由Person.Sex和收集是總和,這意味着收集總結起來使用Integer.sum()方法上的Person.getAge()的返回值變成int值到Integer值。

在第一種情況下,值的集合是按性別列出所有名稱。 Map類型爲Map<Person.Sex, *List<String>*>。這意味着地圖的關鍵是性別,並且存儲的密鑰的值是String(姓名)的List。所以分組需要由Person.Sex和收集是列出名稱,這意味着收集收集他們入使用Collectors.toList()返回相應的收集器的列表變成String值到List<String>值。

+0

中的作用是什麼,我只是更新第三個聚合操作,而我的混淆實際上來自它。現在,它沒有任何Collectors.toList(),但它仍然將值收集到列表中。那麼爲什麼第一個仍然需要List()? – PMH 2014-12-07 04:45:29

+1

在第一種情況下,輸出類型*'String' *與輸入類型*'Person' *不同,因此需要指定其他細節以說明如何從'Person'到'String'。在第三種情況下,輸出類型*'Person' *與輸入類型*'Person' *相同,因此簡單的'groupingBy'方法變體使用默認收集器(這意味着'toList()',但它是以自己的名義進行呼叫,不需要明確的呼叫)。 – 2014-12-07 04:50:02

相關問題