Java Stream:按布尔谓词划分为两个列表
我有一份employees
名单。 它们具有isActive
布尔字段。 我想将employees
分为两个列表: activeEmployees
和formerEmployees
。 是否可以使用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);