【问题标题】:Complexity of equals() in HashMap and SortedMapHashMap 和 SortedMap 中 equals() 的复杂性
【发布时间】:2013-09-21 09:00:08
【问题描述】:

我试图找出 Java 中 HashMap 和 TreeMap 中 equals() 的计算复杂度。现在,您可能会说在这两种情况下它应该是相同的,因为 HashMap 和 TreeMap 都从 AbstractMap 继承了相同的实现。但是,在我完全接受之前,我需要一些解释。

这让我感到困惑。 AbstractMap 文档中重写的 equals() 的部分解释是:

更正式地说,两个映射 m1 和 m2 表示相同的映射,如果 m1.entrySet().equals(m2.entrySet())。

文档不清楚 entrySet 返回的集合是 HashSet 还是 SortedSet 或其他。在我看来,了解这一点很重要,因为它会影响整体分析。

如果 entrySet() 返回的集合是 HashSet 类型,那么可以在 O(n) 中比较两个集合[两个哈希集合的相等成本]。但是,如果它们是 SortedSet 类型,那么它们可以在 O(nlogn) [两个排序集的情况下的相等成本] 中进行比较。因此,在 HashMap 的情况下 equals() 的复杂性与在 SortedMap 的情况下会有所不同,或者至少应该基于我的推理。

我强烈怀疑我的推理在某个地方是错误的,所以请随时告诉我我哪里错了。正确的推理是什么。最后,我对 HashMap 和 SortedMap 的 equals() 的复杂性感兴趣。谢谢。

【问题讨论】:

    标签: java hashmap equals asymptotic-complexity sortedmap


    【解决方案1】:

    我相信你对这两种方法的复杂性都是正确的。由于它们都从 AbstractMap 继承了它们的 equals 实现,因此值得检查 AbstractMap 的源代码。相关部分如下:

    Map<K,V> m = (Map<K,V>) o;
    if (m.size() != size())
        return false;
    
    Iterator<Entry<K,V>> i = entrySet().iterator();
    while (i.hasNext()) {
    Entry<K,V> e = i.next();
    K key = e.getKey();
    V value = e.getValue();
    if (value == null) {
        if (!(m.get(key)==null && m.containsKey(key)))
            return false;
    } else {
        if (!value.equals(m.get(key)))
            return false;
    }
    return true;
    

    请注意,它在内部循环中调用getcontainsKey 方法,这些方法被它们的子类覆盖。由于 HashMap 在 O(1) 中实现这些,而 TreeMap 在 O(log n) 中实现它们,这导致 Hashmap 和 TreeMap 的总体等于复杂度 O(n) 和 O(n log n)。

    【讨论】:

    • 我一直盯着AbstractMap、TreeMap、HashMap这三个中的代码,我觉得我原来的想法毕竟没有错。虽然,TreeMap 和 HashMap 确实都继承了相同的 equals 实现,但真正产生最终区别的是 containskey 和 get 方法。它们都在各自的具体地图类型中被覆盖。在我之前的推理中,我似乎忽略了这一点。谢谢@nitegazer2003
    猜你喜欢
    • 1970-01-01
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    相关资源
    最近更新 更多