如何在Java中连接两个可空集

时间:2012-12-18 20:05:39

标签: java map set

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

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>());

2 个答案:

答案 0 :(得分:5)

我会使用番石榴HashMultimap代替Map<String, Set<String>>。它具有以下优点:

  • 为给定键添加多个值的快捷方法,如果此键不存在,则无需关心
  • 在调用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()作为第二个回退集,以避免不必要的空集创建。并且要小心:您的代码修改了第一组。它没有复制它。所以最后,第一张地图的每一组实际上都是一个合并的集合。

答案 1 :(得分:1)

在某种程度上,这更像是一种风格问题,但有几点需要评论。首先,containsKeyget方法具有相同的成本,因此调用get并检查空返回值更有效。其次,在您的示例中,您将mergedSet设置为firstMap.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);
    }
}