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;
}
}
}
I guess what am I asking is: Can I get a Map.Entry passed to the comparator?
You can’t have the
TreeMapitself sort on the values, since that defies theSortedMapspecification: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.Here’s a generic method that returns a
SortedSetofMap.Entry, given aMapwhose values areComparable:Now you can do the following:
Note that funky stuff will happen if you try to modify either the
SortedSetitself, or theMap.Entrywithin, because this is no longer a “view” of the original map likeentrySet()is.Generally speaking, the need to sort a map’s entries by its values is atypical.
Note on
==forIntegerYour original comparator compares
Integerusing==. This is almost always wrong, since==withIntegeroperands is a reference equality, not value equality.Related questions
new Integer(i) == iin Java? (YES!!!)