[英]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 。 所以对于Cap
和N
非常大的值,复杂度是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 。 因此,对于非常大的Cap
和N
值,复杂度为O(N)
。
另一方面, N
受可用内存量的限制,实际上你需要一个大约2 38字节(256GBytes)的堆,以便N
超过最大可能的Cap
值。 对于大小的地图,最好使用针对大型地图调整的哈希表实现。 或者不使用过大的容量估计!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.