web-dev-qa-db-ja.com

partitioningByの目的は何ですか

たとえば、いくつかの要素を分割する場合は、次のようにします。

Stream.of("I", "Love", "Stack Overflow")
      .collect(Collectors.partitioningBy(s -> s.length() > 3))
      .forEach((k, v) -> System.out.println(k + " => " + v));

出力:

false => [I]
true => [Love, Stack Overflow]

しかし、私にとってpartioningBygroupingByのサブケースにすぎません。前者はPredicateをパラメーターとして受け入れますが、後者はFunctionをパラメーターとして受け入れますが、パーティションを通常のグループ化関数と見なしています。

したがって、同じコードはまったく同じことを行います。

 Stream.of("I", "Love", "Stack Overflow")
       .collect(Collectors.groupingBy(s -> s.length() > 3))
       .forEach((k, v) -> System.out.println(k + " => " + v));

これもMap<Boolean, List<String>>になります。

では、partioningByの代わりにgroupingByを使用する必要がある理由はありますか?ありがとう

33
user2336315

partitioningByは常に、2つのエントリを持つマップを返します。1つは述語が真である場所、もう1つは偽である場所です。両方のエントリに空のリストが含まれる可能性がありますが、それらは存在します。

これは、必要なときにのみエントリを作成するため、groupingByが実行しないことです。

極端な場合、空のストリームをpartitioningByに送信すると、マップには2つのエントリが取得されますが、groupingByは空のマップを返します。

編集:以下で説明するように、この動作はJavaのドキュメントには記載されていませんが、変更すると、現在追加されている値partitioningByが失われます。Java 9これはすでに仕様に含まれています。

35
Oron

partitioningByは、キーが単なるMapである場合に最適化された特別なboolean実装を使用して、少し効率的です。

(また、あなたの意味を明確にするのに役立つかもしれません。partitioningByは、データを分割するために使用されるブール条件があることを効果的に理解するのに役立ちます。)

18
Louis Wasserman

groupingBypartitioningByのもう1つの違いは、前者は_Function<? super T, ? extends K>_を受け取り、後者は_Predicate<? super T>_を取ることです。

メソッド参照またはs -> s.length() > 3などのラムダ式を渡すと、これらの2つのメソッドのいずれかで使用できます(コンパイラーは、選択したメソッドで必要なタイプに基づいて、機能インターフェイスタイプを推測します)。

ただし、_Predicate<T>_インスタンスがある場合は、Collectors.partitioningBy()にのみ渡すことができます。 Collectors.groupingBy()では受け入れられません。

同様に、_Function<T,Boolean>_インスタンスがある場合は、Collectors.groupingBy()にのみ渡すことができます。 Collectors.partitioningBy()では受け入れられません。

2
Eran

partitioningByメソッドは、キーが常にブール値であるマップを返しますが、groupingByメソッドの場合、キーは任意のオブジェクトタイプにすることができます

//groupingBy
Map<Object, List<Person>> list2 = new HashMap<Object, List<Person>>();
list2 = list.stream().collect(Collectors.groupingBy(p->p.getAge()==22));
System.out.println("grouping by age -> " + list2);

//partitioningBy
Map<Boolean, List<Person>> list3 = new HashMap<Boolean, List<Person>>();
list3 = list.stream().collect(Collectors.partitioningBy(p->p.getAge()==22));
System.out.println("partitioning by age -> " + list2);

ご覧のように、partitioningByメソッドの場合のマップのキーは常にブール値ですが、groupingByメソッドの場合、キーはオブジェクトタイプです。

詳細なコードは次のとおりです。

    class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String toString() {
        return this.name;
    }
}

public class CollectorAndCollectPrac {
    public static void main(String[] args) {
        Person p1 = new Person("Kosa", 21);
        Person p2 = new Person("Saosa", 21);
        Person p3 = new Person("Tiuosa", 22);
        Person p4 = new Person("Komani", 22);
        Person p5 = new Person("Kannin", 25);
        Person p6 = new Person("Kannin", 25);
        Person p7 = new Person("Tiuosa", 22);
        ArrayList<Person> list = new ArrayList<>();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        list.add(p4);
        list.add(p5);
        list.add(p6);
        list.add(p7);

        // groupingBy
        Map<Object, List<Person>> list2 = new HashMap<Object, List<Person>>();
        list2 = list.stream().collect(Collectors.groupingBy(p -> p.getAge() == 22));
        System.out.println("grouping by age -> " + list2);

        // partitioningBy
        Map<Boolean, List<Person>> list3 = new HashMap<Boolean, List<Person>>();
        list3 = list.stream().collect(Collectors.partitioningBy(p -> p.getAge() == 22));
        System.out.println("partitioning by age -> " + list2);

    }
}
1
Vaibhav Sharma