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

时间:2017-07-26 11:59:44

标签: java hashmap guava

我正在尝试将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);

以下是错误的屏幕截图: enter image description here

有人可以指出我在做错的地方吗?

2 个答案:

答案 0 :(得分:2)

Multimaps.asMap(multimap)的返回类型为Map<String, <Set<Collection<String>>

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

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

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

答案 1 :(得分:0)

我认为你在这里做的是使用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)而不是SetMultimap#asMap()

  

注意:返回的地图值保证为Set类型。至   使用更具体的泛型类型Map<K, Set<V>>获取此地图,   请改为呼叫Multimaps.asMap(SetMultimap)