【发布时间】:2023-03-20 10:34:01
【问题描述】:
我需要一个支持 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(n-m))
使用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((n-m)*log(n-m))。
对于所有n,m O(n*log(n) + m*log(m) + r*log(n-m)) > O((n-m)*log(n-m))。
因此,我的问题是,TreeMap 比 HashMap 更好的用例是什么?如果您需要多次迭代地图(比如说k),这是否更好(在这种情况下,如果k 是>> log(n) TreeMap 的运行时间将是O(k*(n-m)) 而对于HashMap 将是 O(k*(n-m)*log(n-m)))?不管怎样,如果您只执行 O(log(n)) 迭代(这听起来确实是一个合理的用例),HashMap 将优于 TreeMap。我错过了什么吗?
【问题讨论】:
-
这是针对特定用例的。我的观点是,是否存在 TreeMap 比 HashMap 更好的用例。
-
第二个问题只是说明了区别。我知道这两种地图的区别。如果 TreeMap 总是效率较低,我想知道它为什么存在。
-
如果您需要从一个特定条目开始迭代,那么您应该使用
TreeMap。
标签: java collections