【问题标题】:Efficiency: HashMap check containsKey() vs always put()效率:HashMap 检查 containsKey() vs always put()
【发布时间】:2018-12-14 00:27:44
【问题描述】:

如果我有一个 HashMap 并且我想插入具有很多重复项的键值对,最好这样做: if (!map.containsKey(key)) map.put(key, value); 还是直接使用 map.put(key,value); 而不管键/值对是否已经存在?

【问题讨论】:

  • 这不是关于效率:而是关于你想要什么?只保留第一个并且永远不要覆盖或每次再次找到密钥时覆盖或在现有值和新值之间计算一些东西
  • @azro 键/值对与现有值一样重复,并且特定键的新值始终相同,我只是不确定put 方法是否足够重以进行检查对于现有的密钥值得。

标签: java hashmap


【解决方案1】:

如果您不关心受骗者,请执行map.put(key, value);。这样,您就不会进行额外的 O(1) 查找(包括散列 key,然后检查它是否存在)。

在最坏的情况下,在重复插入完全相同的 (key, value) 对的情况下,这可以节省您对 n-1 的额外查找。

【讨论】:

    【解决方案2】:

    几乎可以肯定的答案是它没有真正的区别。首先得到正确的代码。它的配置文件(您似乎没有做过,或者您对此案例不知道)。不要随意优化/混淆内容,因为这似乎是个好主意。

    通常最大的性能损失是加载和编译代码。因此,最短、最简单的代码可能已经是最优的了。

    【讨论】:

    • 我同意这可能不会有任何区别,尤其是对于我的小数据集。我只是想学习将数据集放入地图的最有效方法。分析它并自己找出结果是一种很好的学习体验,但如果事先完成研究,它会更多地重新发明轮子?我想我主要是想看看 put() 是否足够轻以抵消 containsKey() 中的额外查找。
    【解决方案3】:

    您应该使用方法putIfAbsent。如果您担心覆盖该值。此方法适用于 Java 8 及更高版本。

    put具有相同的时间复杂度。

    如果您可以使用最新值覆盖,请选择put

    【讨论】:

      【解决方案4】:

      putcontain 都具有相同的渐近运行时间,因此使用两者最多将增加 2 倍,这是恒定的。所以你的渐近运行时不会改变。但由于 put 将覆盖任何现有值(甚至返回旧值,如果是新值,则返回 null),因此速度快了 2 倍。

      【讨论】:

        【解决方案5】:

        Map::put 用相同的键覆盖条目,因此.put 不检查映射是否已经包含该键会更有效。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-01-22
          • 2016-02-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-07
          • 2012-04-13
          • 1970-01-01
          相关资源
          最近更新 更多