如何将 Guava HashMultimap 转换为 java.util.Map

How to convert Guava HashMultmap to java.util.Map

我正在尝试将 Guava Multimap<String ,Collection<String>> 转换为 Map<String, Collection<String>>,但在使用 Multimaps.asMap(multimap) 时出现语法错误。这是一个代码:

HashMultimap<String, Collection<String>> multimap = HashMultimap.create();
for (UserDTO dto : employees) {
    if (dto.getDepartmentNames() != null) {
        multimap.put(dto.getUserName().toString().trim(), dto.getDepartmentNames());
    }
}
Map<String, Collection<String>> mapOfSets = Multimaps.asMap(multimap);

错误截图如下:

谁能指出我哪里做错了?

Return Multimaps.asMap(multimap) 的类型是 Map<String, <Set<Collection<String>>

Multimap 可以保存同一个键的多个值。因此,当你想从 multimap 转换为 map 时,你需要为每个键保留值的集合,以防万一有一个键在 map 中出现两次。

如果要从 MultiMap 转换为 Map 并对值设置总和,可以执行以下操作:

Multimaps.asMap(multimap).entrySet().stream()
    .collect(Collectors.toMap(
                 Map.Entry::getKey,
                 e->e.getValue().stream()
                      .flatMap(Collection::stream).collect(toSet())));

我认为你在这里所做的 Multimap 是错误的。 Multimap<String, Collection<String>> 大致相当于 Map<String, Collection<Collection<String>>>,因此在使用 asMap 视图(例如 {user1=[[IT, HR]], user2=[[HR]], user3=[[finance]]})时会导致嵌套集合。

你真正想要的是使用 Multimap<String, String>(更具体地说:SetMultimap<String, String> 对应于 Map<String, Set<String>>)并使用 Multimap#putAll(K, Iterable<V>):

SetMultimap<String, String> multimap = HashMultimap.create();
for (UserDTO dto : employees) {
    if (dto.getDepartmentNames() != null) {
        // note `.putAll` here
        multimap.putAll(dto.getUserName().toString().trim(), dto.getDepartmentNames());
    }
}
Map<String, Set<String>> mapOfSets = Multimaps.asMap(multimap);
// ex. {user1=[HR, IT], user2=[HR], user3=[finance]}

由于 Java 类型系统限制(当子类型嵌套在泛型类型中时不能覆盖泛型类型),使用 Multimaps#asMap(SetMultimap) instead of SetMultimap#asMap() 是必要的:

Note: The returned map's values are guaranteed to be of type Set. To obtain this map with the more specific generic type Map<K, Set<V>>, call Multimaps.asMap(SetMultimap) instead.