[英]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.