TreeMap 按值排序 [英] TreeMap sort by value
问题描述
我想编写一个比较器,让我可以按值而不是默认的自然顺序对 TreeMap 进行排序.
I want to write a comparator that will let me sort a TreeMap by value instead of the default natural ordering.
我尝试过类似的操作,但无法找出问题所在:
I tried something like this, but can't find out what went wrong:
import java.util.*;
class treeMap {
public static void main(String[] args) {
System.out.println("the main");
byValue cmp = new byValue();
Map<String, Integer> map = new TreeMap<String, Integer>(cmp);
map.put("de",10);
map.put("ab", 20);
map.put("a",5);
for (Map.Entry<String,Integer> pair: map.entrySet()) {
System.out.println(pair.getKey()+":"+pair.getValue());
}
}
}
class byValue implements Comparator<Map.Entry<String,Integer>> {
public int compare(Map.Entry<String,Integer> e1, Map.Entry<String,Integer> e2) {
if (e1.getValue() < e2.getValue()){
return 1;
} else if (e1.getValue() == e2.getValue()) {
return 0;
} else {
return -1;
}
}
}
我想我要问的是:我可以将 Map.Entry
传递给比较器吗?
I guess what am I asking is: Can I get a Map.Entry
passed to the comparator?
推荐答案
你不能让 TreeMap
本身对值进行排序,因为这违背了 SortedMap
规范:
You can't have the TreeMap
itself sort on the values, since that defies the SortedMap
specification:
一个Map
,它进一步在其键上提供总排序.
A
Map
that further provides a total ordering on its keys.
但是,使用外部集合,您始终可以对 Map.entrySet()
随心所欲,可以通过键、值,甚至是两者的组合(!!).
However, using an external collection, you can always sort Map.entrySet()
however you wish, either by keys, values, or even a combination(!!) of the two.
这是一个返回 Map.Entry
的 SortedSet
的通用方法,给定一个 Map
,其值为 Comparable
>:
Here's a generic method that returns a SortedSet
of Map.Entry
, given a Map
whose values are Comparable
:
static <K,V extends Comparable<? super V>>
SortedSet<Map.Entry<K,V>> entriesSortedByValues(Map<K,V> map) {
SortedSet<Map.Entry<K,V>> sortedEntries = new TreeSet<Map.Entry<K,V>>(
new Comparator<Map.Entry<K,V>>() {
@Override public int compare(Map.Entry<K,V> e1, Map.Entry<K,V> e2) {
int res = e1.getValue().compareTo(e2.getValue());
return res != 0 ? res : 1;
}
}
);
sortedEntries.addAll(map.entrySet());
return sortedEntries;
}
现在您可以执行以下操作:
Now you can do the following:
Map<String,Integer> map = new TreeMap<String,Integer>();
map.put("A", 3);
map.put("B", 2);
map.put("C", 1);
System.out.println(map);
// prints "{A=3, B=2, C=1}"
System.out.println(entriesSortedByValues(map));
// prints "[C=1, B=2, A=3]"
请注意,如果您尝试修改 SortedSet
本身或其中的 Map.Entry
,将会发生一些奇怪的事情,因为这不再是像 entrySet()
这样的原始地图是.
Note that funky stuff will happen if you try to modify either the SortedSet
itself, or the Map.Entry
within, because this is no longer a "view" of the original map like entrySet()
is.
一般来说,按值对地图条目进行排序的需求是非典型的.
Generally speaking, the need to sort a map's entries by its values is atypical.
您的原始比较器使用 ==
比较 Integer
.这几乎总是错误的,因为带有 Integer
操作数的 ==
是引用相等,而不是值相等.
Your original comparator compares Integer
using ==
. This is almost always wrong, since ==
with Integer
operands is a reference equality, not value equality.
System.out.println(new Integer(0) == new Integer(0)); // prints "false"!!!
相关问题
- 在 Java 中比较两个整数时会自动-发生拆箱?(不!!!)
- 是否保证
new Integer(i) == i
在 Java 中? (YES!!!) - When comparing two Integers in Java does auto-unboxing occur? (NO!!!)
- Is it guaranteed that
new Integer(i) == i
in Java? (YES!!!)
Related questions
这篇关于TreeMap 按值排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!