Java Stream:按布尔谓词划分为两个列表

我有一份employees名单。 它们具有isActive布尔字段。 我想将employees分为两个列表: activeEmployeesformerEmployees 。 是否可以使用Stream API? 什么是最复杂的方式?

Collectors.partitioningBy

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

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

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

有几个原因使用partitioningBy over groupingBy (正如Juan Carlos Mendoza所建议的那样):

首先, groupingBy的参数是一个Function (在这种情况下),因此有可能向它传递一个可以返回null的函数,这意味着如果该函数为任何函数返回null,则会有第3个分区员工 partitioningBy使用Predicate ,因此它只能返回2个分区。

其次,在带有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添加的。

在这种情况下,您还可以使用groupingBy ,因为有2个组可能性(活动和非活动员工):

 Map> grouped = employees.stream() .collect(Collectors.groupingBy(Employee::isActive)); List activeEmployees = grouped.get(true); List formerEmployees = grouped.get(false);