java partitioningBy的目的是什么

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27993604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:46:34  来源:igfitidea点击:

What's the purpose of partitioningBy

javajava-8collectors

提问by user2336315

For example, if I intend to partition some elements, I could do something like:

例如,如果我打算对某些元素进行分区,我可以执行以下操作:

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

which outputs:

输出:

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

But for me partioningByis only a subcase of groupingBy. Although the former accepts a Predicateas parameter while the latter a Function, I just see a partition as a normal grouping function.

但对我partioningBy来说只是groupingBy. 虽然前者接受 aPredicate作为参数,后者接受 a ,但Function我只是将分区视为正​​常的分组功能。

So the same code does exactly the same thing:

所以相同的代码做完全相同的事情:

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

which also results in a Map<Boolean, List<String>>.

这也会导致Map<Boolean, List<String>>.

So is there any reason I should use partioningByinstead of groupingBy? Thanks

那么有什么理由我应该使用partioningBy而不是groupingBy?谢谢

回答by Oron

partitioningBywill always return a map with two entries, one for where the predicate is true and one for where it is false. It is possible that both entries will have empty lists, but they will exist.

partitioningBy将始终返回一个包含两个条目的映射,一个用于谓词为真的地方,一个用于谓词为假的地方。两个条目可能都有空列表,但它们会存在。

That's something that groupingBywill not do, since it only creates entries when they are needed.

这是groupingBy不会做的,因为它只在需要时创建条目。

At the extreme case, if you send an empty stream to partitioningByyou will still get two entries in the map whereas groupingBywill return an empty map.

在极端情况下,如果您向您发送一个空流,partitioningBy您仍然会在地图中获得两个条目,而groupingBy将返回一个空地图。

EDIT: As mentioned below this behavior is not mentioned in the Java docs, however changing it would take away the added value partitioningByis currently providing. For Java 9 this is already in the specs.

编辑:正如下面提到的,Java 文档中没有提到这种行为,但是改变它会带走partitioningBy当前提供的附加值。对于 Java 9,这已经在规范中了。

回答by Louis Wasserman

partitioningByis slightly more efficient, using a special Mapimplementation optimized for when the key is just a boolean.

partitioningBy稍微更有效,使用Map针对键只是 a 时优化的特殊实现boolean

(It might also help to clarify what you mean; partitioningByhelps to effectively get across that there's a boolean condition being used to partition the data.)

(这也可能有助于澄清您的意思;partitioningBy有助于有效地了解使用布尔条件对数据进行分区。)

回答by Eran

Another difference between groupingByand partitioningByis that the former takes a Function<? super T, ? extends K>and the latter a Predicate<? super T>.

groupingByand之间的另一个区别partitioningBy是前者采用 a Function<? super T, ? extends K>,后者采用 a Predicate<? super T>

When you pass a method reference or a lambda expression, such as s -> s.length() > 3, they can be used by either of these two methods (the compiler will infer the functional interface type based on the type required by the method you choose).

当您传递方法引用或 lambda 表达式时,例如s -> s.length() > 3,它们可以被这两种方法中的任何一种使用(编译器将根据您选择的方法所需的类型推断功能接口类型)。

However, if you have a Predicate<T>instance, you can only pass it to Collectors.partitioningBy(). It won't be accepted by Collectors.groupingBy().

但是,如果您有Predicate<T>实例,则只能将其传递给Collectors.partitioningBy(). 不会被接受Collectors.groupingBy()

And similarly, if you have a Function<T,Boolean>instance, you can only pass it to Collectors.groupingBy(). It won't be accepted by Collectors.partitioningBy().

同样,如果您有一个Function<T,Boolean>实例,则只能将其传递给Collectors.groupingBy(). 不会被接受Collectors.partitioningBy()

回答by Vaibhav Sharma

partitioningBymethod will return a map whose key is always a Boolean value, but in case of groupingBymethod, the key can be of any Object type

partitioningBy方法将返回一个映射,其键始终为布尔值,但在groupingBy方法的情况下,键可以是任何 Object 类型

//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);

As you can see, the key for map in case of partitioningBy method is always a Boolean value, but in case of groupingBy method, the key is Object type

如您所见,partitioningBy 方法中map 的key 始终是布尔值,而groupingBy 方法中的key 是Object 类型

Detailed code is as follows:

详细代码如下:

    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);

    }
}