Rud*_*koŭ 15 java collections reduce functional-programming java-stream
我有一份清单employees.他们有isActive布尔字段.我想employees分成两个列表:activeEmployees和formerEmployees.是否可以使用Stream API?什么是最复杂的方式?
And*_*ner 20
Map<Boolean, List<Employee>> partitioned =
listOfEmployees.stream().collect(
Collectors.partitioningBy(Employee::isActive));
Run Code Online (Sandbox Code Playgroud)
生成的映射包含两个列表,对应于谓词是否匹配:
List<Employee> activeEmployees = partitioned.get(true);
List<Employee> formerEmployees = partitioned.get(false);
Run Code Online (Sandbox Code Playgroud)
有几个原因,使用partitioningBy了groupingBy(由所建议的胡安·卡洛斯·门多萨):
首先,参数groupingBy是a Function<Employee, Boolean>(在这种情况下),因此有可能向它传递一个可以返回null的函数,这意味着如果该函数为任何一个雇员返回null,则会有第三个分区.partitioningBy使用a Predicate<Employee>,所以它只能返回2个分区.
其次,在得到的地图中得到两个列表(*)NullPointerException; 使用Map.computeIfAbsent,您只获得键/值对,其中元素映射到给定键:
System.out.println(
Stream.empty().collect(Collectors.partitioningBy(a -> false)));
// Output: {false=[], true=[]}
System.out.println(
Stream.empty().collect(Collectors.groupingBy(a -> false)));
// Output: {}
Run Code Online (Sandbox Code Playgroud)
(*)Java 8 Javadoc中没有记录此行为,但它是为Java 9添加的.
在这种情况下,您还可以使用groupingBy,因为有 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);
Run Code Online (Sandbox Code Playgroud)
最尖端的方法是什么?
Java 12 当然有新的Collectors::teeing
List<List<Employee>> divided = employees.stream().collect(
Collectors.teeing(
Collectors.filtering(Employee::isActive, Collectors.toList()),
Collectors.filtering(Predicate.not(Employee::isActive), Collectors.toList()),
List::of
));
System.out.println(divided.get(0)); //active
System.out.println(divided.get(1)); //inactive
Run Code Online (Sandbox Code Playgroud)