Java 8 将 Map<Department, List<Person>> 转换为 Map<Department, List<String>>

Java 8 convert Map<Department, List<Person>> to Map<Department, List<String>>

使用 Collectors.groupingBy() 我可以轻松获得 Map<Department, List<Person>> - 这为我提供了属于 Department:

的所有 Person 对象
allPersons.stream().collect(Collectors.groupingBy(Person::getDepartment));

现在我想转换结果 'multimap' 以便它包含所有人员的姓名而不是 Person 对象。

实现此目的的一种方法是:

final Map<Department, List<String>> newMap = new HashMap<>();
personsByDepartmentMap.stream
    .forEach((d, lp) -> newMap.put(
         d, lp.stream().map(Person::getName).collect(Collectors.toList())));

有没有不使用 newMap 对象就可以实现的方法? 像

final Map<Department, List<String>> newMap = 
                personsByDepartmentMap.stream().someBigMagic();

您可以使用

转换地图
Map<Department, List<String>> result =
    personsByDepartmentMap.entrySet().stream()
      .map(e -> new AbstractMap.SimpleImmutableEntry<>(
        e.getKey(),
        e.getValue().stream().map(Person::getName).collect(Collectors.toList())))
  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

这段代码显然没有标准的 Pair 类型,但您可以使用 static imports 改进它。

(更新:)作为 在这种特定情况下,您可以通过将映射和集合合并为一个步骤来解决它,例如

Map<Department, List<String>> result =personsByDepartmentMap.entrySet().stream()
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        e->e.getValue().stream().map(Person::getName).collect(Collectors.toList())));

不过,我仍然认为通过一次操作从您的原始 List 中检索地图更容易:

Map<Department, List<String>> collect = allPersons.stream()
    .collect(Collectors.groupingBy(
        Person::getDepartment,
        Collectors.mapping(Person::getName, Collectors.toList())
    ));

这也将受益于 static imports:

Map<Department, List<String>> collect = allPersons.stream().collect(
    groupingBy(Person::getDepartment, mapping(Person::getName, toList())));
Map<Dept, List<String>> namesInDept
    = peopleInDept.entrySet().stream()
                  .collect(toMap(Map.Entry::getKey, 
                                 e -> e.getValue().stream()
                                                  .map(Person::getName)
                                                  .collect(toList()));

我怀疑您不需要中介 Map<Person, List<Department>> 类型。如果是这样,您可以一步完成:

Map<Department, List<String>> result = allPersons.stream().collect(
    Collectors.groupingBy(Person::getDepartment,
        Collectors.mapping(Person::getName, Collectors.toList())
    )
);