partitioningBy的目的是什么?

use*_*315 30 java java-8 collectors

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

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

哪个输出:

false => [I]
true => [Love, Stack Overflow]
Run Code Online (Sandbox Code Playgroud)

但对我partioningBy来说只是一个子问题groupingBy.虽然前者Predicate在后者a中接受as参数Function,但我只看到一个分区作为正常的分组函数.

所以相同的代码完全相同:

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

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

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

Oro*_*ron 38

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

这是不可行的groupingBy,因为它只在需要时创建条目.

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

编辑:如下所述,Java文档中未提及此行为,但更改它会带走partitioningBy当前提供的附加值.对于Java 9,这已经在规范中.

  • 这是最合理的行为,但我没有看到javadoc中两个条目的保证.我在http://stackoverflow.com/questions/41287517/must-partitioningby-produce-a-map-with-entries-for-true-and-false上提出了一个问题. (2认同)

Lou*_*man 18

partitioningBy稍微提高效率,使用一个特殊的Map实现,优化的时候只是一个键boolean.

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

  • 考虑到Java API的普遍强烈偏好,不包括便利的特殊方法,我有点惊讶,因为它包含它所需的所有论证.轻微的性能优势和轻微的澄清.我看到Doug Lea的想法:) (7认同)
  • @Mghostsoft看看我链接的问题,答案说保证是在Java 9的javadoc中添加的. (2认同)