浅谈Java之Map 按值排序 (Map sort by value)
map是键值对的集合,又叫作字典或关联数组等,是最常见的数据结构之一。在java如何让一个map按value排序呢? 看似简单,但却不容易!
比如,map中key是string类型,表示一个单词,而value是int型,表示该单词出现的次数,现在我们想要按照单词出现的次数来排序:
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);
按值排序的结果应该是:
key value me 1000 you 3000 and 4000 hungry 5000 later 6000 food 10000
首先,不能采用sortedmap结构,因为sortedmap是按键排序的map,而不是按值排序的map,我们要的是按值排序的map。
couldn't you do this with a sortedmap?
no, because the map are being sorted by its keys.
方法一:
如下java代码:
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; } }
类似的c++代码:
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);
上面方法的实质意义是:将map结构中的键值对(map.entry)封装成一个自定义的类(结构),或者直接用map.entry类。自定义类知道自己应该如何排序,也就是按值排序,具体为自己实现comparable接口或构造一个comparator对象,然后不用map结构而采用有序集合(sortedset, treeset是sortedset的一种实现),这样就实现了map中sort by value要达到的目的。就是说,不用map,而是把map.entry当作一个对象,这样问题变为实现一个该对象的有序集合或对该对象的集合做排序。既可以用sortedset,这样插入完成后自然就是有序的了,又或者用一个list或数组,然后再对其做排序(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.
方法二:
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} 或者还可以这样: 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]
另外,groovy 中实现 sort map by value,当然本质是一样的,但却很简洁 :
用 groovy 中 map 的 sort 方法(需要 groovy 1.6),
def result = map.sort(){ a, b -> b.value.compareto(a.value) }
如:
["a":3,"b":1,"c":4,"d":2].sort{ a,b -> a.value - b.value }
结果为: [b:1, d:2, a:3, c:4]
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)]
以上这篇浅谈java之map 按值排序 (map sort by value)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
上一篇: NoteBook 资讯
下一篇: 深入理解Java中的克隆
推荐阅读
-
浅谈Java之Map 按值排序 (Map sort by value)
-
java8 实现map以value值排序操作
-
java8的新特性,Collections.sort(排序的List集合)的使用,对list封装Map里面的某个值进行排序
-
利用ArrayList对map进行按key(键)和按value (值) 排序
-
Java Map按Key值进行排序
-
java8 实现map以value值排序操作
-
Java Map 按key排序和按Value排序的实现方法
-
java的Map集合中按value值进行排序输出的实例代码
-
浅谈Java之Map 按值排序 (Map sort by value)
-
Java Map 按key排序和按Value排序的实现方法