Map is a collection of key-value pairs, also known as dictionaries or associative arrays, etc., and is one of the most common data structures. How to sort a map by value in Java? It seems simple, but not easy!
For example, in Map, the key is String type, which represents a word, and the value is int type, which represents the number of times the word appears. Now we want to sort by the number of times the word appears:
Map map = new TreeMap();map.put("me", 1000);map.put("and", 4000);map.put("you", 3000);map.put("food", 10000);map.put("hungry", 5000);map.put("later", 6000); The result of sorting by value should be:
key valueme 1000you 3000and 4000hungry 5000later 6000food 10000
First of all, we cannot adopt the SortedMap structure, because SortedMap is a map sorted by keys, not a map sorted by value. What we want is a map sorted by value.
Couldn't you do this with a SortedMap?
No, because the map are being sorted by its keys.
Method 1:
The following Java code:
import java.util.Iterator;import java.util.Set;import java.util.TreeSet;public class Main { public static void main(String[] args) { Set set = new TreeSet(); set.add(new Pair("me", "1000")); set.add(new Pair("and", "4000")); set.add(new Pair("you", "3000")); set.add(new Pair("food", "10000")); set.add(new Pair("hungry", "5000")); set.add(new Pair("later", "6000")); set.add(new Pair("myself", "1000")); for (Iterator i = set.iterator(); i.hasNext();) System.out.println(i.next()); }}class Pair implements Comparable { private final String name; private final int number; public Pair(String name, int number) { this.name = name; this.number = number; } public Pair(String name, String number) throws NumberFormatException { this.name = name; this.number = Integer.parseInt(number); } public int compareTo(Object o) { if (o instanceof Pair) { int cmp = Double.compare(number, ((Pair) o).number); if (cmp != 0) { return cmp; } return name.compareTo(((Pair) o).name); } throw new ClassCastException("Cannot compare Pair with " + o.getClass().getName()); } public String toString() { return name + ' ' + number; }} Similar C++ code:
typedef pair<string, int> PAIR;int cmp(const PAIR& x, const PAIR& y){ return x.second > y.second;}map<string,int> m;vector<PAIR> vec;for (map<wstring,int>::iterator curr = m.begin(); curr != m.end(); ++curr){ vec.push_back(make_pair(curr->first, curr->second));}sort(vec.begin(), vec.end(), cmp); The essential significance of the above method is: encapsulate the key-value pair (Map.Entry) in the Map structure into a custom class (struct), or use the Map.Entry class directly. Custom classes know how to sort themselves, that is, sort by value, specifically implement the Comparable interface or construct a Comparator object for themselves, and then use an ordered set without using the Map structure (SortedSet, TreeSet is an implementation of SortedSet), which realizes the purpose of sort by value in the Map. That is to say, instead of using Map, Map.Entry is regarded as an object, so that the problem becomes to implement an ordered set of the object or sorting the set of the object. You can use SortedSet, so that after insertion is completed, it will naturally be ordered, or use a List or array, and then sort it (Collections.sort() or Arrays.sort()).
Encapsulate the information in its own class. Either implement
Comparable and write rules for the natural ordering or write a
Comparator based on your criteria. Store the information in a sorted
collection, or use the Collections.sort() method.
Method 2:
You can also use the following code to sort by value:
public static Map sortByValue(Map map) { List list = new LinkedList(map.entrySet()); Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { 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; } public static Map sortByValue(Map map, final boolean reverse) { List list = new LinkedList(map.entrySet()); Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { if (reverse) { return -((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } 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; } Map map = new HashMap(); map.put("a", 4); map.put("b", 1); map.put("c", 3); map.put("d", 2); Map sorted = sortByValue(map); System.out.println(sorted);// output : {b=1, d=2, c=3, a=4} Or it can be done like this: Map map = new HashMap(); map.put("a", 4); map.put("b", 1); map.put("c", 3); map.put("d", 2); Set<Map.Entry<String, Integer>> treeSet = new TreeSet<Map.Entry<String, Integer>>( new Comparator<Map.Entry<String, Integer>>() { public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { Integer d1 = o1.getValue(); Integer d2 = o2.getValue(); int r = d2.compareTo(d1); if (r != 0) return r; else return o2.getKey().compareTo(o1.getKey()); } }); treeSet.addAll(map.entrySet()); System.out.println(treeSet); // output : [a=4, c=3, d=2, b=1] In addition, implementing sort map by value in Groovy is of course the essence is the same, but it is very simple:
Use the sort method of map in groovy (requires groovy 1.6).
def result = map.sort(){ a, b -> b.value.compareTo(a.value) } like:
["a":3,"b":1,"c":4,"d":2].sort{ a,b -> a.value - b.value }
The result is: [b:1, d:2, a:3, c:4]
Similar in Python:
h = {"a":2,"b":1,"c":3}i = h.items() // i = [('a', 2), ('c', 3), ('b', 1)]i.sort(lambda (k1,v1),(k2,v2): cmp(v2,v1) ) // i = [('c', 3), ('a', 2), ('b', 1)]The above article briefly talks about Java Map sort by value is all the content I share with you. I hope it can give you a reference and I hope you can support Wulin.com more.