3

我有两个地图,其中一个 String 作为键,Set 作为它的值。这两个映射可以共享相同的键。如果两个地图具有相同的键,我正在尝试将两个 Set 值合并在一起。问题是,第二个映射可能为空,并且由于并非所有键都在两个映射之间共享,因此集合也可能为空。我想出了几个选项,但它们看起来都很乱。想知道是否有人有更有效/更漂亮的方法。这是我到目前为止所拥有的:

Set<String> mergedSet = (firstMap.containsKey(commonKey)) ? firstMap.get(commonKey) : new HashSet<String>();

mergedSet.addAll(secondMap != null && secondMap.containsKey(commonKey) ? secondMap.get(commonKey) : new HashSet<String>());

4

2 回答 2

5

我会使用 Guava 的HashMultimap而不是Map<String, Set<String>>. 它具有以下优点:

  • 为给定键添加多个值的快捷方法,而不关心该键是否已存在 Set
  • 调用时总是返回一个非空的 Set get(key),即使没有为此键存储任何内容。

所以你的代码会变成:

Set<String> mergedSet = Sets.union(firstMultimap.get(commonKey),
                                   secondMultimap.get(commonKey));

该集合将只是两个集合的视图,这避免了复制每个元素。但是如果你想要一个副本,那就做

Set<String> mergedSet = Sets.newHashSet(Sets.union(firstMultimap.get(commonKey),
                                                   secondMultimap.get(commonKey)));

如果您不想使用外部库,那么您的代码就可以了。我会使用Collections.singletonSet()第二个后备集,以避免不必要的空集创建。请注意:您的代码修改了第一组。它不会复制它。所以最后,第一张地图的每一组实际上都是一个合并的集合。

于 2012-12-18T20:21:51.437 回答
1

在某种程度上,这更多是风格问题,但有几点需要评论。首先,containsKeyandget方法的成本相等,因此调用get和检查 null 返回值更有效。其次,在您的示例中,您将设置设置为mergedSetfirstMap.get(commonKey)这意味着您正在修改集合,firstMap它将是合并的集合。我猜你不想修改firstMap. 我建议使用更长的时间:

Set<String> mergedSet = new HashSet<String>();

Set<String> firstSet = firstMap.get(commonKey);
if (firstSet != null)
{
    mergedSet.addAll(firstSet);
}

if (secondMap != null)
{
    Set<String> secondSet = secondMap.get(commonKey);
    if (secondSet != null)
    {
        mergedSet.addAll(secondSet);
    }
}
于 2012-12-18T20:37:01.430 回答