簡體   English   中英

如果數據沒有變化,我應該使用什么類型的地圖?

[英]What type of Map should I use if the data does not change?

我有要按鍵查找的數據。

我的特殊用例是,一旦地圖初始化,數據(鍵/值和元素數量)就不會改變。 所有鍵/值值都是一次已知的。

我通常為此使用帶有默認構造函數的 HashMap(默認初始容量和負載因子)。

構建此地圖的最佳方法是什么? 如果我要使用 HashMap,應該將默認初始容量和負載因子設置為多少? Map.copyOf() 是更好的解決方案嗎? 地圖的大小是否重要(20 個元素對 140,000 個)?

這篇文章https://docs.oracle.com/en/java/javase/15/core/creating-immutable-lists-sets-and-maps.html#GUID-6A9BAE41-A1AD-4AA1-AF1A-A8FC99A14199似乎暗示Map.copyOf() 返回的非可變 Map 更節省空間。

在大多數情況下, HashMap已經相當接近最優了。 桶數組的容量每次翻倍,所以當你有 (2^N) + 1 個項目時最浪費,因為容量必然是 2^(N+1)(即 2049 個項目需要 4096 的容量,但 2048項目完美契合)。

在您的情況下,指定初始大小只會在創建地圖時阻止一些重新分配,如果它只發生一次可能是不相關的。 負載因子不相關,因為地圖的容量永遠不會改變。 無論如何,如果您確實想預先調整大小,這將是正確的:

new HashMap<>(numItems, 1);

地圖的大小是否重要(20 個元素對 140,000 個)?

它會產生影響,但不會產生巨大影響。 項目被分組到存儲桶中,存儲桶被構造為列表或樹。 因此性能主要取決於給定存儲桶中有多少項目,而不是所有存儲桶中的項目總數。

重要的是項目在您的存儲桶中的均勻分布。 糟糕的哈希碼實現將導致聚類。 我相信,集群將開始將 O(1) 操作移向 O(log n)。

// The worst possible hashCode impl.
@Override
public int hashCode() { return 0; } // or any other constant 

如果您在應用程序的多次調用中具有相同的項目(從問題中不清楚是否是這種情況),並且如果鍵的類在您的控制之下,那么您可以奢侈地調整hashCode 實現對分布產生積極影響,例如通過使用不同的素數作為模數。 然而,這將是反復試驗,實際上只是一個微優化。

至於解決如何賦予不變性的評論/答案,我認為這是一個單獨的問題。 首先找出什么地圖實際上是最佳的,然后擔心如何賦予它不變性,如果它還沒有的話。 您始終可以在Collections.unmodifiableMap中包裝可變映射。 據說Guava 的 ImmutableMap 比 HashMap 慢,我懷疑其他不可變變體也將難以超過 HashMap 的性能。

看看這篇文章: https ://www.baeldung.com/java-immutable-maps。 有一些現成的實現,包括您在問題中提到的那個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM