繁体   English   中英

java.util.HashMap 类的 keySet() 方法的时间复杂度是多少?

[英]What is the time complexity of java.util.HashMap class' keySet() method?

我正在尝试实现平面扫描算法,为此我需要知道java.util.HashMap 类的 keySet()方法的时间复杂度。 我怀疑它是 O(n log n)。 我对么?

澄清点:我说的是keySet()方法的时间复杂度; 遍历返回的 Set 显然需要 O(n) 时间。

获取密钥集是O(1)并且便宜。 这是因为HashMap.keyset()返回与HashMap关联的实际KeySet对象。

返回的Set不是的副本,而是实际HashMap状态的包装器。 事实上,如果你更新集合,你实际上可以改变HashMap的状态; 例如,在集合上调用clear()将清除HashMap


...遍历返回的Set显然需要O(n)时间。

实际上,这并不总是正确的:

  • HashMap是使用new HashMap<>() 最坏的情况是让所有N密钥都位于同一个哈希链中。 但是,如果映射自然增长,散列数组中仍然会有N个条目和O(N)个槽。 因此,迭代条目集将涉及O(N)操作。

  • 如果HashMap是使用new HashMap<>(capacity)和非常糟糕(太大)的capacity估计创建的,则为假。 然后将需要O(Cap) + O(N)操作来迭代条目集。 如果我们将Cap视为一个变量,那就是O(max(Cap, N)) ,这可能比O(N)更糟糕。

不过有一个转义条款。 由于capacity在当前HashMap API 中是一个int ,因此Cap是 2 31 所以对于CapN非常大的值,复杂度是O(N)

另一方面, N受可用内存量的限制,实际上您需要一个数量级为 2 38字节 (256GBytes) 的堆,以便N超过可能的最大Cap值。 对于这种大小的地图,最好使用针对大型地图进行调整的哈希表实现。 或者不使用过大的容量估计!

肯定是O(1)。 它所做的只是在 HashMap 上返回一个包装对象。

如果您正在谈论遍历键集,那么这是 O(n),因为每个 next() 调用都是 O(1),并且这需要执行 n 次。

这应该在 O(n) 时间内是可行的......哈希映射通常被实现为一个大的存储桶数组,存储桶的大小(通常)与哈希映射的大小成正比。 为了检索密钥集,必须迭代存储桶,并且对于每个设置项,必须检索密钥(通过中间集合或直接访问存储桶的迭代器)...

**编辑:正如其他人所指出的,实际的 keyset() 方法将在 O(1) 时间内运行,但是,迭代键集或将其传输到专用集合将是 O(n) 操作。 不太确定您要找哪一个 **

Java 集合有很多空间,因此不会占用太多时间。 我相信这种方法是 O(1)。 收藏品只是坐在那里。

为了解决“遍历返回的 Set 显然需要 O(n) 时间”的注释,根据HashMap文档注释,这实际上并不正确:

迭代集合视图需要的时间与 HashMap 实例的“容量”(桶的数量)加上它的大小(键值映射的数量)成正比。 因此,如果迭代性能很重要,则不要将初始容量设置得太高(或负载因子太低),这一点非常重要。

所以换句话说,迭代返回的Set将花费O(n + c) ,其中n是地图的大小, c是它的容量,而不是O(n) 如果选择了大小不合适的初始容量或负载因子,则c的值可能会在迭代时间方面超过地图的实际大小。

切线答案:

...迭代返回的Set将显然花费O(n)时间。

实际上并非总是如此:

  • 使用new HashMap<>()创建HashMap是正确的。 最糟糕的情况是让所有N密钥都落在同一个哈希链中。 但是,如果地图自然增长,则哈希数组中仍将有N个条目和O(N)个插槽。 因此,迭代条目集将涉及O(N)操作。

  • 如果使用new HashMap<>(capacity)和非常差(太大)的capacity估计创建HashMap ,则为false。 然后,将采用O(Cap) + O(N)操作来迭代条目集。 如果我们将Cap视为变量,那就是O(max(Cap, N)) ,这可能比O(N)更差。

但是有一个逃避条款。 由于capacity是当前HashMap API中的int ,因此Cap为2 31 因此,对于非常大的CapN值,复杂度为O(N)

另一方面, N受可用内存量的限制,实际上你需要一个大约2 38字节(256GBytes)的堆,以便N超过最大可能的Cap值。 对于大小的地图,最好使用针对大型地图调整的哈希表实现。 或者不使用过大的容量估计!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM