我需要像 TreeMap 这样的排序地图,但按值排序。我的地图会很大,所以我不能在需要的时候对地图进行排序。有什么好的解决方案来解决这个问题吗?也许存在满足这个的外部罐子?
4 回答
有多种方法可以满足您的要求。正如您随后澄清的那样,您的当前 . 中可能有重复的对象TreeMap
,也许您可以TreeMap
用第三方多图(Guava、Apache Commons Collections)替换您的,然后交换您的键和值 - 即替换为. 根据您的具体情况,我相信这很有可能为您工作。TreeMap<Key, Value>
Multimap<Value, Key>
实际上并不存在任何可以有效执行此操作的数据结构:您必须维护一个数据结构,以便通过键查找更高效,并且对值进行排序会使维护该结构变得更加困难。
但是,如果您在创建地图后不修改地图,那么您可以执行以下操作:
List<Map.Entry<Key, Value>> list = new ArrayList<Map.Entry<Key, Value>>(
map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Key, Value>>() {
public int compare(Map.Entry<Key, Value> e1, Map.Entry<Key, Value> e2) {
return e1.getValue().compareTo(e2.getValue());
}
});
Map<Key, Value> sortedByValues = new LinkedHashMap<Key, Value>();
for (Map.Entry<Key, Value> entry : list) {
sortedByValues.put(entry.getKey(), entry.getValue());
}
生成的 LinkedHashMap 将按排序值顺序进行迭代。
如果您使用TreeMap
来维护您的值的索引,即您主要使用它来快速找到给定键的匹配值,那么您可以做的另一件事是保留 2 个数据结构:
- 您现在
TreeMap
用于索引的 - A
PriorityQueue
(或其他排序列表)以排序顺序迭代您的值
然后,当您有任何更改时,只需在两个列表中添加和删除值。为此,您不需要保留两个值的副本。您可以简单地将您现在拥有的一份副本添加到两个列表中,因为这些列表仅适用于对您的值的引用。
如果您的数据是唯一的,您可以将它们保存在一个Set
可以按升序迭代的中(假设您实现Comparable
)。
然后,您可以Map
单独持有,而无需花费太多额外费用,而不仅仅是持有原件Map
。