首页 > 解决方案 > 如何从过滤的流中从多个映射中收集键集?

问题描述

我正在尝试学习使用流和收集器,我知道如何使用多个 for 循环来做到这一点,但我想成为一个更有效率的程序员。

每个项目都有一个映射committedHoursPerDay,其中键是员工,值是用整数表示的小时数。我想遍历所有项目的committedHoursPerDay 地图并过滤committedHoursPerDay 超过7(全职)的地图,并将每个全职工作的员工添加到集合中。

到目前为止我写的代码是这样的:

    public Set<Employee> getFulltimeEmployees() {
        // TODO
        Map<Employee,Integer> fulltimeEmployees = projects.stream().filter(p -> p.getCommittedHoursPerDay().entrySet()
                .stream()
                .filter(map -> map.getValue() >= 8)
                .collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue())));


        return fulltimeEmployees.keySet();
    }

但是过滤器可以识别映射,因为我可以访问键和值,但是在 .collect(Collectors.toMap()) 中它不识别映射并且仅将其视为 lambda 参数

在此处输入图像描述

标签: javastreammappingcollectors

解决方案


这里有一对多的概念。您可以首先使用扁平化地图flatMap,​​然后将其应用于filter地图条目。

Map<Employee,Integer> fulltimeEmployees = projects.stream()
                .flatMap(p -> p.getCommittedHoursPerDay()
                        .entrySet()
                        .stream())
                .filter(mapEntry  -> mapEntry.getValue() >= 8)
                .collect(Collectors.toMap(mapEntry -> mapEntry.getKey(), mapEntry -> mapEntry.getValue()));

flatMap步骤返回一个Stream<Map.Entry<Employee, Integer>>. 因此filter在 a 上运行Map.Entry<Employee, Integer>

您还可以在收集步骤中使用方法参考作为.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))


推荐阅读