【问题标题】:Big-O: Getting all of the keys in a Java HashMapBig-O:获取 Java HashMap 中的所有键
【发布时间】:2012-08-07 20:08:21
【问题描述】:

有人知道Java HashMap中keySet的摊销分析是什么吗? O(1)?

正在遍历它们O(n)

【问题讨论】:

    标签: java amortized-analysis


    【解决方案1】:

    map.keySet() 只是返回一个对存储在映射中的键集的引用,因此它显然是一个 O(1) 操作。

    然后迭代是对该集合的循环,该集合本身在内部使用映射的桶上的循环,因此操作所需的时间与 n+m 成正比,其中 n 是键集的大小,m 是地图的容量.

    因此,如果您的地图容量非常大,只有一个条目,那么即使只有一个键,对 keySet 的迭代也会遍历所有桶。

    不知道你是如何用 big-o 表示法翻译的。

    我刚刚对两张地图进行了快速测试,每张地图都有一个条目。一张地图的容量为 1000 万,另一张的容量为 1。对 keyset(两种情况下都是一项)的迭代需要大地图的 3,500 倍时间(18,843,092 ns 对 5434 ns)。

    ps:和javadoc of HashSet 说的差不多:

    迭代这个集合需要的时间与 HashSet 实例的大小(元素的数量)加上支持 HashMap 实例的“容量”(桶的数量)的总和成正比。因此,如果迭代性能很重要,那么不要将初始容量设置得太高(或负载因子太低),这一点非常重要。

    【讨论】:

    • +1 如果你使用 LinkedHashMap 迭代是 O(n) 而不管容量。
    • @assylias 你能解释一下这个“迭代然后是对该集合的循环,它本身在内部使用映射桶上的循环”。可能对这一行的解释将是[对我的问题的回答][(HashSet 上的迭代成本还取决于支持映射的容量?)]
    • @Geek 不确定您不了解哪一部分。 for (Key k : map.keyset()) 是对键集的迭代,它恰好是一个集合。这相当于使用迭代器。如果您查看集合的迭代器的代码,您会发现它循环遍历每个映射桶,无论集合中的项目数量是多少。因此,如果集合只有一个项目,但地图有 10,000,000 个项目,则迭代该集合将意味着迭代 10,000,000 个地图的桶,仅获取一个项目。
    • @assylias +1 进行澄清。它帮助我接受了我的问题的答案。但是为什么不是 n*m 而是 n+m 呢?
    【解决方案2】:

    您可以检查source code 的keySet。

    基于 this 迭代 Set 是 O(n)

    【讨论】:

    • 发布依赖链接的答案不是一个好习惯。如果您的一个或多个链接停止工作(例如 1 现在适合我),它会破坏您的答案的未来使用。
    猜你喜欢
    • 2019-07-13
    • 2014-01-06
    • 2016-03-08
    • 2011-02-10
    • 1970-01-01
    • 2016-03-09
    • 1970-01-01
    • 2010-11-25
    相关资源
    最近更新 更多