【发布时间】:2020-01-19 04:50:04
【问题描述】:
我有一个类似的方法:
static List<Employee> getEmployeesByFactoryAndTask(
ProtectedMap<String, Factory> factoryMap, String factoryName, Task task) {
return factoryMap.values().stream()
.filter(factory -> factory.getName().equals(factoryName))
.map(Factory::getEmployees)
.flatMap(Optional::stream)
.flatMap(Collection::stream)
.filter(employee -> employee.getTask().equals(task))
.collect(Collectors.toList());
}
假设过滤器 Employees 集合由 factoryName 和 Task 枚举参数。
上面的代码工作正常,但我想在我的 ProtectedMap 类中使用辅助方法find:
public class ProtectedMap<T, U> extends HashMap<T, U> {
public Optional<U> find(T key) {
return Optional.ofNullable(super.get(key));
}
}
得到相同的结果。
到目前为止,我的方法如下所示:
return factoryMap
.find(factoryName)
.stream()
.map(Factory::getEmployees)
.flatMap(Optional::stream)
.flatMap(Collection::stream)
.collect(Collectors.toMap(Employee::getTask, Function.identity()));
但我不知道我想把第二个方法调用find 放在哪里,它会被Task 过滤以获得desribale 效果。附带说明一下,Factory 包含两个字段:Optional<List<Employees>> 和 String,这是工厂的名称。
对于如何解决问题的建议,我将不胜感激。
【问题讨论】:
-
您真正想要实现的目标是什么?您希望给定工厂的所有员工都有给定的任务?
-
是的,我想要一个使用 find 方法 Usage 按两个条件过滤的员工列表。
-
首先,阻止
Factory将集合包装成可选项。一个空集合已经足以表明没有元素。然后,您可以使用return factoryMap .find(factoryName) .map(f -> f.getEmployees().stream().collect(Collectors.toMap( Employee::getTask, Function.identity()))) .orElse(Collections.emptyMap()); -
不惜一切代价尝试引入那种琐碎的
find方法是没有意义的。如果你想要一个特定的任务,根本不要收集到Map:而不是.collect(Collectors.toMap(Employee::getTask, Function.identity())),使用.filter(employee -> employee.getTask().equals(task)) .collect(Collectors.toList()) -
我的第二条评论独立于“包含在可选列表中的列表”问题。只需使用
return factoryMap .find(factoryName) .stream() .flatMap(f -> f.getEmployees().map(Collection::stream).orElse(null)) .filter(employee -> employee.getTask().equals(task)) .collect(Collectors.toList());
标签: java functional-programming java-stream java-11