簡體   English   中英

何時使用TreeMap代替HashMap

[英]When to use TreeMap instead of HashMap

我需要一個支持3種操作的映射:“插入”,“刪除”和“按排序順序迭代”。 這正是Java中TreeMap的接口。 話雖如此,也可以通過使用HashMap並在每次迭代之前對其進行排序來實現。 為了分析不同的方法,可以說我執行n插入, m刪除,“ r”讀取然后進行迭代。

使用TreeMap我們可以執行以下操作:

TreeMap<Integer, Integer> tm = Maps.newTreeMap();
for (int i=0;i<n;++i) {tm.put(i, 2*i);} // O(n*log(n))
for (int i=0;i<m;++i) {tm.remove(i);} // O(m*log(m))
for (int i=0;i<r;++i) {tm.get(i);} // O(r*log(n-m))
for (Integer i : tm) {print(i);} // O(n-m)

總而言之,我們的總運行時間為O(n*log(n) + m*log(m) + r*log(nm))

使用HashMap我們可以執行以下操作:

HashMap<Integer, Integer> hm = Maps.newHashMap();
for (int i=0;i<n;++i) {hm.put(i, 2*i);} // O(n)
for (int i=0;i<m;++i) {hm.remove(i);} // O(m)
for (int i=0;i<r;++i) {hm.get(i);} // O(r)
List<Integer> sortedList = Lists.newArrayList(hm.keySet()); // O(n-m)
Collections.sort(sortedList); // O((n-m)*log(n-m))
for (Integer i : sortedList) {print(i);} // O(n-m)

總而言之,我們的總運行時間為O((nm)*log(nm))

對於所有n,m O(n*log(n) + m*log(m) + r*log(nm)) > O((nm)*log(nm))

因此,我的問題是, TreeMapHashMap更好的用例是什么? 僅當您需要多次遍歷地圖(比如說k )(在這種情況下,如果k為>> log(n)時, TreeMap的運行時間將為O(k*(nm))時,它是否更好? HashMap將是O(k*(nm)*log(nm)))嗎? 無論如何,如果僅執行O(log(n))迭代(這聽起來像是一種合理的用例),則HashMap性能將優於TreeMap 我想念什么嗎?

當然存在這樣的用例。 在所有重讀設置中,您都可以在插入期間僅排序一次。 與您的問題的假設相反,大多數用例都是閱讀量很大的。

當您需要提取在鍵上具有上限或下限的子圖,查找最小或最大鍵或查找最接近給定鍵的鍵時, TreeMap可以提供更大的優勢。 NavigableMap接口專用於這些操作。

一個明顯的用例是當您要根據一些Comparator定義對地圖進行排序時。 並非總是與性能有關。

暫無
暫無

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

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