合并两个地图

2022-09-01 12:49:56

我有两个映射,它们的键是s,其值为。给定两个 s,最简单的方法来合并它们,如果两个键相同,则该值是两个集合的并集。您可以假设值永远不会为空,如果它有用,我们可以使这些 s。StringSet<MyObject>MapMapSortedMap


答案 1

您可以相当轻松地使用执行此操作:

Map<T, Set<U>> merged = Stream.of(first, second)
        .map(Map::entrySet)
        .flatMap(Set::stream)
        .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a, b) -> {
            HashSet<U> both = new HashSet<>(a);
            both.addAll(b);
            return both;
        }));

这会将映射拆分为它们的 s,然后将它们与收集器连接,该收集器通过将两个值添加到新 .EntryHashSet

这也适用于任意数量的地图。

产生相同结果的一些变体:

Stream.of(first, second).flatMap(m -> m.entrySet().stream())
    .collect(...);
Stream.concat(first.entrySet().stream(), second.entrySet().stream())
    .collect(...); //from comment by Aleksandr Dubinsky

如果没有重复的键,则 不需要 的第三个参数。Collectors.toMap

还有另一个 Collectors.toMap,其中包含第四个参数,可让您决定收集到的类型。Map


答案 2

我们是在谈论实例吗?在这种情况下,查找是 O(1),所以你只能获取一个映射,迭代该映射的条目,查看另一个映射是否包含该键。如果没有,只需添加该集。如果它包含键,则取两个集合的并集(通过将一个集合的所有元素添加到另一个集合)HashMap

用一些代码来说明,我在哪里使用Set在我的IDE中具有自动完成功能

Map<String, Set<Double>> firstMap = new HashMap<String, Set<Double>>(  );
Map<String, Set<Double>> secondMap = new HashMap<String, Set<Double>>(  );
Set<Map.Entry<String, Set<Double>>> entries = firstMap.entrySet();
for ( Map.Entry<String, Set<Double>> entry : entries ) {
  Set<Double> secondMapValue = secondMap.get( entry.getKey() );
  if ( secondMapValue == null ) {
    secondMap.put( entry.getKey(), entry.getValue() );
  }
  else {
    secondMapValue.addAll( entry.getValue() );
  }
}