Java 流:按布尔谓词分为两个列表
2022-09-01 06:45:43
我有一个列表。它们具有布尔字段。我想分成两个列表:和.是否可以使用流 API 执行操作?最复杂的方法是什么?employees
isActive
employees
activeEmployees
formerEmployees
我有一个列表。它们具有布尔字段。我想分成两个列表:和.是否可以使用流 API 执行操作?最复杂的方法是什么?employees
isActive
employees
activeEmployees
formerEmployees
Map<Boolean, List<Employee>> partitioned =
listOfEmployees.stream().collect(
Collectors.partitioningBy(Employee::isActive));
生成的映射包含两个列表,对应于谓词是否匹配:
List<Employee> activeEmployees = partitioned.get(true);
List<Employee> formerEmployees = partitioned.get(false);
有几个理由使用over(正如Juan Carlos Mendoza所建议的那样):partitioningBy
groupingBy
首先,参数是 a(在本例中),因此有可能向它传递一个可以返回 null 的函数,这意味着如果该函数对任何雇员返回 null,则将有第 3 个分区。这将导致收集器抛出:虽然没有显式记录,但显式为空键引发异常,可能是因为partitioningBy
使用谓词<Employee>
,因此它只能返回 2 个分区。Map.computeIfAbsent
的行为“如果函数返回null则不记录映射”,这意味着元素将从输出中静默删除。(感谢lczapski指出这一点)。groupingBy
Function<Employee, Boolean>
NullPointerException
其次,在生成的映射中得到两个列表(*);;使用 ,您只能获得元素映射到给定键的键/值对: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: {}
在这种情况下,您还可以使用分组By,因为有2个组可能性(活跃和非活跃员工):
Map<Boolean, List<Employee>> grouped = employees.stream()
.collect(Collectors.groupingBy(Employee::isActive));
List<Employee> activeEmployees = grouped.get(true);
List<Employee> formerEmployees = grouped.get(false);