【问题标题】:How to join two nullable sets in Java如何在 Java 中加入两个可空集
【发布时间】:2012-12-06 02:41:02
【问题描述】:

我有两个映射,其中一个 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>());

【问题讨论】:

  • 强烈建议您永远拥有可以是null 的集合。如果您在初始化时使用空集合,您将避免代码中出现各种特殊情况(或运行时 NPE)。这个建议在许多 Java 资源中,例如javapractices.com/topic/TopicAction.do?Id=59
  • @AndrewLazarus:虽然我同意你的观点,但在这种情况下,OP 没有将集合初始化为 null。他只是没有在第二个映射中存储第一个映射中存在的键的集合。这就是为什么 Guava 的多张地图如此酷炫的原因。
  • @JBNizet,我不是 100% 确定,但我认为 secondMap 本身并没有存储在地图中,最后一行暗示它可能为空。

标签: java map set


【解决方案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);
    }
}

【讨论】:

    【解决方案2】:

    我会使用 Guava 的 HashMultimap 而不是 Map&lt;String, Set&lt;String&gt;&gt;。它具有以下优点:

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

    所以你的代码会变成:

    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() 作为第二个后备集,以避免不必要的空集创建。请注意:您的代码修改了第一组。它不会复制它。所以最后,第一张地图的每一组其实都是一个合并的集合。

    【讨论】:

    • 这听起来很像Guava issue 912,对于Multimaps.union(SetMultimap, SetMultimap) 和/或Multimaps.concat(ListMultimap, ListMultimap)
    • 我认为 HashMap 没有比这更好的了,但如果 OP 出于其他原因已经在使用 TreeMap,最好设置一个合并。
    猜你喜欢
    • 2017-04-21
    • 1970-01-01
    • 2017-08-10
    • 2020-09-03
    • 2023-03-10
    • 2011-01-07
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    相关资源
    最近更新 更多