web-dev-qa-db-ja.com

Java8を使用して述語でリストを分割する方法は?

いくつかの小さなリストに分割したいリストaがあります。

「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.の前はとても古かった。

21
Elad Benda

@ RealSkepticcomment で説明したように、Predicateはtrueとfalseの2つの結果のみを返すことができます。これは、データを2つのグループにのみ分割できることを意味します。
必要なのは、一緒にグループ化する必要のある要素の一般的な結果を決定できる、ある種のFunctionです。あなたの場合、そのような結果は小文字の最初の文字になる可能性があります(すべての文字列が空ではない場合-少なくとも1つの文字を含む)。

Collectors.groupingBy(function) を使用すると、すべての要素を個別のリストにグループ化し、キーをグループ化に使用する共通の結果(最初の文字など)にマップに格納できます。

したがって、コードは次のようになります。

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]}
30
Pshemo

_Collectors.groupingBy_ を使用して、(グループ化)->(そのグループ化されたもののリスト)のストリームをオンにできます。グループ化自体を気にしない場合は、そのマップでvalues()を呼び出して、パーティションの_Collection<List<String>>_を取得します。

5
yshavit