Java 流 : divide into two lists by boolean predicate

标签 java collections functional-programming java-stream reduce

我有一份员工的列表。他们有 isActive boolean 字段。我想将 employees 分成两个列表:activeEmployeesformerEmployees。是否可以使用 Stream API?什么是最复杂的方法?

最佳答案

Collectors.partitioningBy :

Map<Boolean, List<Employee>> partitioned = 
    listOfEmployees.stream().collect(
        Collectors.partitioningBy(Employee::isActive));

生成的映射包含两个列表,对应于谓词是否匹配:

List<Employee> activeEmployees = partitioned.get(true);
List<Employee> formerEmployees = partitioned.get(false);

使用 partitioningBy 有几个原因在 groupingBy (如 Juan Carlos Mendoza 所建议):

首先是groupingBy的参数是 Function<Employee, Boolean> (在这种情况下),因此有可能向它传递一个可以返回 null 的函数, 意味着如果该函数为任何员工返回 null,则将有第三个分区。 partitioningBy使用 Predicate<Employee> ,所以它只能返回 2 个分区。 这将导致 NullPointerException被收集器抛出:虽然没有明确记录,但会为空键显式抛出异常,大概是因为 Map.computeIfAbsent 的行为“如果函数返回 null,则不记录任何映射”,这意味着元素将从输出中静默删除。 (感谢 lczapski 指出这一点)。

其次,您在生成的 map 中使用 partitioningBy 获得两个列表 (*) ;与 groupingBy ,您只会获得元素映射到给定键的键/值对:

System.out.println(
    Stream.empty().collect(Collectors.partitioningBy(a -> false)));
// Output: {false=[], true=[]}

System.out.println(
    Stream.empty().collect(Collectors.groupingBy(a -> false)));
// Output: {}

(*) 此行为未记录在 Java 8 Javadoc 中, 但它是为 Java 9 添加的.

关于Java 流 : divide into two lists by boolean predicate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46958023/

相关文章:

haskell - 为什么FRP将时间作为值(value)的一个因素?

java - 如何获取 JTextPane 中输入文本的高度?

java - 错误消息 : operator < cannot be applied to boolean, 整数

java - 在 Java 中使用长列表作为映射键

java - Groovy 比较除第一项之外的两个集合

javascript - 如何一起提升和组合功能?

java - 将经典代码更改为函数式代码

java - 在电话上运行 tess-two

java - 如何在 Java 中增加 Map 中特定键的值?

c# - 实现父子类层次结构