2016-04-17 39 views
9

我有一個列表a,我想分成幾個小列表。如何通過使用java8謂詞分區列表?

說出所有包含「aaa」的項目,所有包含「bbb」和更多謂詞的項目。

如何使用java8來做到這一點?

我看到這個post,但它只分成2個列表。

public void partition_list_java8() { 

    Predicate<String> startWithS = p -> p.toLowerCase().startsWith("s"); 

    Map<Boolean, List<String>> decisionsByS = playerDecisions.stream() 
      .collect(Collectors.partitioningBy(startWithS)); 

    logger.info(decisionsByS); 

    assertTrue(decisionsByS.get(Boolean.TRUE).size() == 3); 
} 

我看到這個post,但它是很老,JAVA 8

+2

謂詞是布爾值。它只是「真」和「假」。我認爲在你的情況下使用'Function'和'Collectors :: groupingBy'會更好。 – RealSkeptic

回答

22

就像它在@RealSkeptic中解釋的那樣commentPredicate只能返回兩個結果:true和false。這意味着您只能分兩組來分割數據。
你需要的是某種Function,這將允許你確定一些應該被分組在一起的元素的共同結果。在你的情況下,這樣的結果可能是小寫的第一個字符(假設所有字符串都不是空的 - 至少有一個字符)。

現在使用Collectors.groupingBy(function)您可以將所有元素分組在單獨的列表中,並將它們存儲在Map中,其中鍵將成爲用於分組的常用結果(如第一個字符)。

所以,你的代碼可以像

Function<String, Character> firstChar = s -> Character.toLowerCase(s.charAt(0)); 

List<String> a = Arrays.asList("foo", "Abc", "bar", "baz", "aBc"); 
Map<Character, List<String>> collect = a.stream() 
     .collect(Collectors.groupingBy(firstChar)); 

System.out.println(collect); 

輸出:

{a=[Abc, aBc], b=[bar, baz], f=[foo]} 
2

您可以使用Collectors.groupingBy把你的(分組)流之前 - >(在分組的事情列表)。如果您不關心這些分組,那麼請在該地圖上撥打values()以獲得分區的Collection<List<String>>