Sorting the Map<Key,Value> in descending order based on the value
Solution 1
Since you can have duplicate values you shouldn't be using a Set
at all. Change to a List
and sort it instead. Your entriesSortedByValues
would look something like this:
static <K,V extends Comparable<? super V>>
List<Entry<K, V>> entriesSortedByValues(Map<K,V> map) {
List<Entry<K,V>> sortedEntries = new ArrayList<Entry<K,V>>(map.entrySet());
Collections.sort(sortedEntries,
new Comparator<Entry<K,V>>() {
@Override
public int compare(Entry<K,V> e1, Entry<K,V> e2) {
return e2.getValue().compareTo(e1.getValue());
}
}
);
return sortedEntries;
}
Note: in your example output the values is descending. If you want them ascending, use e1.getValue().compareTo(e2.getValue())
instead.
Example:
public static void main(String args[]) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("A", 34);
map.put("B", 25);
map.put("C", 50);
map.put("D", 50); // "duplicate" value
System.out.println(entriesSortedByValues(map));
}
Output:
[D=50, C=50, A=34, B=25]
Solution 2
Write your own comparator
and pass it to TreeMap
class MyComparator implements Comparator {
Map map;
public MyComparator(Map map) {
this.map = map;
}
public int compare(Object o1, Object o2) {
return ((Integer) map.get(o2)).compareTo((Integer) map.get(o1));
}
}
In Test Class
Map<String, Integer> lMap=new HashMap<String, Integer>();
lMap.put("A", 35);
lMap.put("B", 25);
lMap.put("C", 50);
MyComparator comp=new MyComparator(lMap);
Map<String,Integer> newMap = new TreeMap(comp);
newMap.putAll(lMap);
OutPut:
C=50
A=35
B=25
NandaKumar
Updated on July 26, 2020Comments
-
NandaKumar almost 4 years
Possible Duplicate:
How to sort a Map<Key, Value> on the values in Java?I am using map interface to read from a file and then store the values in that as a key value pair. The file format is as follows
A 34 B 25 c 50
I will read the datas from this file and store that as a key value pair and then I will display this to the user. My requirement is to display the results in this format
C 50 A 34 B 25
Thus I need to sort the map in descending order of the value. So that I will be able to display these as my result .. I have read about this and find the below code
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; // Special fix to preserve items with equal values } } ); sortedEntries.addAll(map.entrySet()); return sortedEntries; }
I hope this is gonna sort the values in ascending order, I just want to know whether this approach is correct or some other effective approach will be helpful for me ?
-
dacwe almost 12 yearsThis doesn't work if you add
lMap.put("D", 50)
since it would be considered as a duplicate (and would in fact override any other value with50
e.g."C"
). -
amicngh almost 12 yearsduplicate value is not allowed .
-
NandaKumar almost 12 years@amicngh: Thank you for your kind solution. But,I want the duplicate value to be allowed . What would be the possible way to get the same. Thank you.
-
Learner over 8 yearsThe following code will work. public Map sortByValue(Map map) { List list = new LinkedList(map.entrySet()); Collections.sort(list, new Comparator() { public int compare(Object o2, Object o1) { return ((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } }); Map result = new LinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); result.put(entry.getKey(), entry.getValue()); } return result; }
-
Even Cheng almost 8 yearsWorks for me. Thanks!
-
Tell Me How over 7 yearsYou should use new TreeMap(Collections.reverseOrder());. Map<String, Integer> newMap = new TreeMap(Collections.reverseOrder()); newMap.putAll(myMap);
-
SocketByte over 6 yearsEveryone looking at this should use
sortedEntries.sort()
instead ofCollections
like that:sortedEntries.sort((e1, e2) -> e2.getValue().compareTo(e1.getValue()));
-
acacia about 3 years@NandaKumar you could add an if clause in the compareTo method on what to do if both the values are same. For e.g , here I'm ordering by keys in descending order if two values are same. public int compare(Object o1, Object o2) { if(map.get(o2) == map.get(o1)) return o2.toString().compareTo(o1.toString()); return ((Integer) map.get(o2)).compareTo((Integer) map.get(o1));