【问题标题】:What is the cost of ContainsAll in Java?Java 中 ContainsAll 的成本是多少?
【发布时间】:2012-04-17 21:55:21
【问题描述】:

我今天在一些编码过程中发现了containsAll()(List 接口方法),它看起来很漂亮。有谁知道这在性能/迭代方面的成本是多少?

documentation 在这方面提供的不多。

【问题讨论】:

    标签: java arrays list interface


    【解决方案1】:
    • 首先,它迭代所提供集合的每个元素
    • 然后它迭代列表的所有元素并使用.equals(..) 将当前元素与它们进行比较(注意:这是关于列表,正如您在问题中指定的那样。其他集合的行为不同)

    所以它是 O(n*m),其中 n 和 m 是两个集合的大小。

    public boolean containsAll(Collection<?> c) {
        Iterator<?> e = c.iterator();
        while (e.hasNext())
            if (!contains(e.next()))
            return false;
        return true;
    }
    

    【讨论】:

    • 您的第二个要点假定contains() 的通用实现,但HashSet/HashMap 在O(1) 中完成,任何排序的集合都可能在O(logn) 中完成。
    • @PhilippReichart 我知道,但问题是指列表
    • 哦,对了。我的思绪飘到 Collection.containsAll() 的原始定义上,它被 List.containsAll() 覆盖。
    • 其实不是。我复制的 sn-p 来自 AbstractCollection。我添加了关于不同集合(地图、集合)的注释)。但是当他提到列表时,我将重点放在那里
    • 爆炸,我也很怀疑。谢谢!我很高兴你提到 HashMap 有类似的东西——我下次会考虑使用它。
    【解决方案2】:

    使用来源,卢克 :)

    编辑:正如 Bozho 指出的那样,您问的是 List.containsAll() 覆盖 Collection.containsAll()。下面的漫谈主要与后者有关:

    大多数Collection 类将使用implementation of containsAll from AbstractCollection,它是这样的:

    public boolean containsAll(Collection<?> c) {
        for (Object e : c)
            if (!contains(e))
                return false;
        return true;
    }
    

    但不能保证某些实现会完全不同——这可能会导致更好或更差的运行时行为。

    containsAll 的上述实现将至少为 O(n),其中 n 是您传入的 Collection 参数中的项目数,加号无论contains 需要什么时间:

    • 对于HashSet/HashMap,这可能是 O(1)(最好的情况,没有冲突),所以 containsAll 的整体运行时间仍然是 O(n)
    • 对于ArrayList,contains 将占用 O(m),其中 m 是列表中的项目数(不是参数),因此 containsAll 的总时间为 O(n*m)

    【讨论】:

    • 嗯,这是addAll 的实现,而不是containsAll。但是 OP:对于大多数实现,containsAll 成本 O(n^2);它没有做任何特别酷的事情。
    • @LouisWasserman 糟糕,复制粘贴了错误的代码块。固定。
    • 澄清一下:这适用于大多数List 实现。 containsAll 通常需要 O(n) 乘以 contains 查询的成本。
    【解决方案3】:

    如果您正在调用 A.containsAll(B)

    openjdk 迭代 B 调用 A.contains(b) 的所有元素。

    A.contains(b) 迭代 A 的所有元素,调用 a.equals(b)

    这是来自open jdk 7的源代码

    【讨论】:

    • 特定的集合类可能会覆盖contains() 以提供更好的实现。想想HashSet。
    • 同意。我没有费心去查看 AbstractCollection 的每个实现。
    【解决方案4】:

    考虑

    n.ContainsAll(m)

    最好的情况是 O(m),如果 n 是一个完美的哈希集。

    考虑到未排序的列表,我可以提出一个 O(n*log(n) + m*log(m)) 算法

    【讨论】:

      猜你喜欢
      • 2012-02-20
      • 2012-05-13
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多