7

这个问题涉及使用 java 8 收集器对元素进行映射和分组。我有一份病人名单。每个患者都有他访问过的部门的列表。假设我想计算每个部门使用 java 8 中的新收集器 API 访问了多少次,我将如何按部门列表分组?

谢谢!

注意:我知道我可以在每个部门设置一个柜台,这个问题完全是为了学习新的 java 8 特性。

代码:

public class Patient {
    private String id;
    private List<Department> history;
    /* some more getters/setters come here */
}

在我的主要方法中,我有一个患者列表。我想知道每个部门,它被访问了多少次,而不编辑部门类(或扩展或装饰它)。

我想我必须采取一系列患者并将它们映射到部门->计数的地图(每个患者访问哪个部门的次数)。拥有这些地图的流 - 我不知道如何对这些地图进行分组并计算它们。

4

1 回答 1

11

首先,我假设如果患者多次访问某个科室,该科室将多次出现在患者的历史列表中。

如果是这种情况,那么我们可以简单地将我们的患者流和flatMap它带到科室流,其中科室的出现表明患者有一次就诊。

然后我们可以将它传递给groupingBy收集器。我们要按部门本身进行分类,所以分类器函数就是恒等函数。

对于该值,如果 Department 的条目尚不存在,我们希望将 1 作为值,但如果存在条目,我们希望将 1 添加到现有值。有一个名为的收集器counting()已经为我们完成了这项工作,因此我们只需将其作为下游收集器传递给groupingBy().

结果代码如下:

import static java.util.stream.Collectors.*;

List<Patient> patients = ... ;

Map<Department, Long> frequency =
    patients.stream()
        .flatMap(p -> p.getHistory().stream())
        .collect(groupingBy(d -> d, counting()));

请注意,如果一个部门没有被访问过,它只会从地图中消失。如果你有一个部门列表,你可以像这样填写零值:

departments.forEach(d -> frequency.putIfAbsent(d, 0L));

或者如果你想在get边上填零,

long numVisits = frequency.getOrDefault(dept, 0L);
于 2014-04-26T01:23:04.413 回答