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] 

但对我来说, partioningBy只是groupingBy一个子句。 虽然前者接受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>

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

partitioningBy将始终返回一个包含两个条目的映射,一个用于谓词为true,另一个用于false。 两个条目都可能具有空列表,但它们将存在。

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

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

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

partitioningBy稍微高效一点,使用一个特殊的Map实现,当key只是一个boolean时进行了优化。

(它可能也有助于澄清你的意思; partitioningBy有助于有效地了解有一个布尔条件用于分区数据。)

groupingBypartitioningBy之间的另一个区别是前者采用了一个Function Function Function ,后者是Predicate Predicate

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

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

同样,如果你有一个Function实例,你只能将它传递给Collectors.groupingBy()Collectors.partitioningBy()不会接受它。

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

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

正如您所看到的,在partitioningBy方法的情况下,map的键始终是布尔值,但在groupingBy方法的情况下,键是Object类型

详细代码如下:

  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 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> list2 = new HashMap>(); list2 = list.stream().collect(Collectors.groupingBy(p -> p.getAge() == 22)); System.out.println("grouping by age -> " + list2); // partitioningBy Map> list3 = new HashMap>(); list3 = list.stream().collect(Collectors.partitioningBy(p -> p.getAge() == 22)); System.out.println("partitioning by age -> " + list2); } }